summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2016-09-21 22:25:21 -0700
committerMark Adler <madler@alumni.caltech.edu>2016-09-21 22:51:15 -0700
commit9aaec95e82117c1cb0f9624264c3618fc380cecb (patch)
treee2911e6cc7351c0c0b44017a5089c66101daa00c
parent3fb251b363866417122fe54a158a1ac5a7837101 (diff)
downloadzlib-9aaec95e82117c1cb0f9624264c3618fc380cecb.tar.gz
zlib-9aaec95e82117c1cb0f9624264c3618fc380cecb.tar.bz2
zlib-9aaec95e82117c1cb0f9624264c3618fc380cecb.zip
Use post-increment only in inffast.c.
An old inffast.c optimization turns out to not be optimal anymore with modern compilers, and furthermore was not compliant with the C standard, for which decrementing a pointer before its allocated memory is undefined. Per the recommendation of a security audit of the zlib code by Trail of Bits and TrustInSoft, in support of the Mozilla Foundation, this "optimization" was removed, in order to avoid the possibility of undefined behavior.
-rw-r--r--inffast.c81
1 files changed, 31 insertions, 50 deletions
diff --git a/inffast.c b/inffast.c
index bda59ce..f0d163d 100644
--- a/inffast.c
+++ b/inffast.c
@@ -10,25 +10,6 @@
10 10
11#ifndef ASMINF 11#ifndef ASMINF
12 12
13/* Allow machine dependent optimization for post-increment or pre-increment.
14 Based on testing to date,
15 Pre-increment preferred for:
16 - PowerPC G3 (Adler)
17 - MIPS R5000 (Randers-Pehrson)
18 Post-increment preferred for:
19 - none
20 No measurable difference:
21 - Pentium III (Anderson)
22 - M68060 (Nikl)
23 */
24#ifdef POSTINC
25# define OFF 0
26# define PUP(a) *(a)++
27#else
28# define OFF 1
29# define PUP(a) *++(a)
30#endif
31
32/* 13/*
33 Decode literal, length, and distance codes and write out the resulting 14 Decode literal, length, and distance codes and write out the resulting
34 literal and match bytes until either not enough input or output is 15 literal and match bytes until either not enough input or output is
@@ -96,9 +77,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
96 77
97 /* copy state to local variables */ 78 /* copy state to local variables */
98 state = (struct inflate_state FAR *)strm->state; 79 state = (struct inflate_state FAR *)strm->state;
99 in = strm->next_in - OFF; 80 in = strm->next_in;
100 last = in + (strm->avail_in - 5); 81 last = in + (strm->avail_in - 5);
101 out = strm->next_out - OFF; 82 out = strm->next_out;
102 beg = out - (start - strm->avail_out); 83 beg = out - (start - strm->avail_out);
103 end = out + (strm->avail_out - 257); 84 end = out + (strm->avail_out - 257);
104#ifdef INFLATE_STRICT 85#ifdef INFLATE_STRICT
@@ -119,9 +100,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
119 input data or output space */ 100 input data or output space */
120 do { 101 do {
121 if (bits < 15) { 102 if (bits < 15) {
122 hold += (unsigned long)(PUP(in)) << bits; 103 hold += (unsigned long)(*in++) << bits;
123 bits += 8; 104 bits += 8;
124 hold += (unsigned long)(PUP(in)) << bits; 105 hold += (unsigned long)(*in++) << bits;
125 bits += 8; 106 bits += 8;
126 } 107 }
127 here = lcode[hold & lmask]; 108 here = lcode[hold & lmask];
@@ -134,14 +115,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
134 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 115 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
135 "inflate: literal '%c'\n" : 116 "inflate: literal '%c'\n" :
136 "inflate: literal 0x%02x\n", here.val)); 117 "inflate: literal 0x%02x\n", here.val));
137 PUP(out) = (unsigned char)(here.val); 118 *out++ = (unsigned char)(here.val);
138 } 119 }
139 else if (op & 16) { /* length base */ 120 else if (op & 16) { /* length base */
140 len = (unsigned)(here.val); 121 len = (unsigned)(here.val);
141 op &= 15; /* number of extra bits */ 122 op &= 15; /* number of extra bits */
142 if (op) { 123 if (op) {
143 if (bits < op) { 124 if (bits < op) {
144 hold += (unsigned long)(PUP(in)) << bits; 125 hold += (unsigned long)(*in++) << bits;
145 bits += 8; 126 bits += 8;
146 } 127 }
147 len += (unsigned)hold & ((1U << op) - 1); 128 len += (unsigned)hold & ((1U << op) - 1);
@@ -150,9 +131,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
150 } 131 }
151 Tracevv((stderr, "inflate: length %u\n", len)); 132 Tracevv((stderr, "inflate: length %u\n", len));
152 if (bits < 15) { 133 if (bits < 15) {
153 hold += (unsigned long)(PUP(in)) << bits; 134 hold += (unsigned long)(*in++) << bits;
154 bits += 8; 135 bits += 8;
155 hold += (unsigned long)(PUP(in)) << bits; 136 hold += (unsigned long)(*in++) << bits;
156 bits += 8; 137 bits += 8;
157 } 138 }
158 here = dcode[hold & dmask]; 139 here = dcode[hold & dmask];
@@ -165,10 +146,10 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
165 dist = (unsigned)(here.val); 146 dist = (unsigned)(here.val);
166 op &= 15; /* number of extra bits */ 147 op &= 15; /* number of extra bits */
167 if (bits < op) { 148 if (bits < op) {
168 hold += (unsigned long)(PUP(in)) << bits; 149 hold += (unsigned long)(*in++) << bits;
169 bits += 8; 150 bits += 8;
170 if (bits < op) { 151 if (bits < op) {
171 hold += (unsigned long)(PUP(in)) << bits; 152 hold += (unsigned long)(*in++) << bits;
172 bits += 8; 153 bits += 8;
173 } 154 }
174 } 155 }
@@ -196,30 +177,30 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
196#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 177#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
197 if (len <= op - whave) { 178 if (len <= op - whave) {
198 do { 179 do {
199 PUP(out) = 0; 180 *out++ = 0;
200 } while (--len); 181 } while (--len);
201 continue; 182 continue;
202 } 183 }
203 len -= op - whave; 184 len -= op - whave;
204 do { 185 do {
205 PUP(out) = 0; 186 *out++ = 0;
206 } while (--op > whave); 187 } while (--op > whave);
207 if (op == 0) { 188 if (op == 0) {
208 from = out - dist; 189 from = out - dist;
209 do { 190 do {
210 PUP(out) = PUP(from); 191 *out++ = *from++;
211 } while (--len); 192 } while (--len);
212 continue; 193 continue;
213 } 194 }
214#endif 195#endif
215 } 196 }
216 from = window - OFF; 197 from = window;
217 if (wnext == 0) { /* very common case */ 198 if (wnext == 0) { /* very common case */
218 from += wsize - op; 199 from += wsize - op;
219 if (op < len) { /* some from window */ 200 if (op < len) { /* some from window */
220 len -= op; 201 len -= op;
221 do { 202 do {
222 PUP(out) = PUP(from); 203 *out++ = *from++;
223 } while (--op); 204 } while (--op);
224 from = out - dist; /* rest from output */ 205 from = out - dist; /* rest from output */
225 } 206 }
@@ -230,14 +211,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
230 if (op < len) { /* some from end of window */ 211 if (op < len) { /* some from end of window */
231 len -= op; 212 len -= op;
232 do { 213 do {
233 PUP(out) = PUP(from); 214 *out++ = *from++;
234 } while (--op); 215 } while (--op);
235 from = window - OFF; 216 from = window;
236 if (wnext < len) { /* some from start of window */ 217 if (wnext < len) { /* some from start of window */
237 op = wnext; 218 op = wnext;
238 len -= op; 219 len -= op;
239 do { 220 do {
240 PUP(out) = PUP(from); 221 *out++ = *from++;
241 } while (--op); 222 } while (--op);
242 from = out - dist; /* rest from output */ 223 from = out - dist; /* rest from output */
243 } 224 }
@@ -248,35 +229,35 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
248 if (op < len) { /* some from window */ 229 if (op < len) { /* some from window */
249 len -= op; 230 len -= op;
250 do { 231 do {
251 PUP(out) = PUP(from); 232 *out++ = *from++;
252 } while (--op); 233 } while (--op);
253 from = out - dist; /* rest from output */ 234 from = out - dist; /* rest from output */
254 } 235 }
255 } 236 }
256 while (len > 2) { 237 while (len > 2) {
257 PUP(out) = PUP(from); 238 *out++ = *from++;
258 PUP(out) = PUP(from); 239 *out++ = *from++;
259 PUP(out) = PUP(from); 240 *out++ = *from++;
260 len -= 3; 241 len -= 3;
261 } 242 }
262 if (len) { 243 if (len) {
263 PUP(out) = PUP(from); 244 *out++ = *from++;
264 if (len > 1) 245 if (len > 1)
265 PUP(out) = PUP(from); 246 *out++ = *from++;
266 } 247 }
267 } 248 }
268 else { 249 else {
269 from = out - dist; /* copy direct from output */ 250 from = out - dist; /* copy direct from output */
270 do { /* minimum length is three */ 251 do { /* minimum length is three */
271 PUP(out) = PUP(from); 252 *out++ = *from++;
272 PUP(out) = PUP(from); 253 *out++ = *from++;
273 PUP(out) = PUP(from); 254 *out++ = *from++;
274 len -= 3; 255 len -= 3;
275 } while (len > 2); 256 } while (len > 2);
276 if (len) { 257 if (len) {
277 PUP(out) = PUP(from); 258 *out++ = *from++;
278 if (len > 1) 259 if (len > 1)
279 PUP(out) = PUP(from); 260 *out++ = *from++;
280 } 261 }
281 } 262 }
282 } 263 }
@@ -313,8 +294,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
313 hold &= (1U << bits) - 1; 294 hold &= (1U << bits) - 1;
314 295
315 /* update state and return */ 296 /* update state and return */
316 strm->next_in = in + OFF; 297 strm->next_in = in;
317 strm->next_out = out + OFF; 298 strm->next_out = out;
318 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); 299 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
319 strm->avail_out = (unsigned)(out < end ? 300 strm->avail_out = (unsigned)(out < end ?
320 257 + (end - out) : 257 - (out - end)); 301 257 + (end - out) : 257 - (out - end));