Skip to content

Commit 9aaec95

Browse files
committed
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.
1 parent 3fb251b commit 9aaec95

File tree

1 file changed

+31
-50
lines changed

1 file changed

+31
-50
lines changed

inffast.c

Lines changed: 31 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,6 @@
1010

1111
#ifndef ASMINF
1212

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-
3213
/*
3314
Decode literal, length, and distance codes and write out the resulting
3415
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 */
9677

9778
/* copy state to local variables */
9879
state = (struct inflate_state FAR *)strm->state;
99-
in = strm->next_in - OFF;
80+
in = strm->next_in;
10081
last = in + (strm->avail_in - 5);
101-
out = strm->next_out - OFF;
82+
out = strm->next_out;
10283
beg = out - (start - strm->avail_out);
10384
end = out + (strm->avail_out - 257);
10485
#ifdef INFLATE_STRICT
@@ -119,9 +100,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
119100
input data or output space */
120101
do {
121102
if (bits < 15) {
122-
hold += (unsigned long)(PUP(in)) << bits;
103+
hold += (unsigned long)(*in++) << bits;
123104
bits += 8;
124-
hold += (unsigned long)(PUP(in)) << bits;
105+
hold += (unsigned long)(*in++) << bits;
125106
bits += 8;
126107
}
127108
here = lcode[hold & lmask];
@@ -134,14 +115,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
134115
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
135116
"inflate: literal '%c'\n" :
136117
"inflate: literal 0x%02x\n", here.val));
137-
PUP(out) = (unsigned char)(here.val);
118+
*out++ = (unsigned char)(here.val);
138119
}
139120
else if (op & 16) { /* length base */
140121
len = (unsigned)(here.val);
141122
op &= 15; /* number of extra bits */
142123
if (op) {
143124
if (bits < op) {
144-
hold += (unsigned long)(PUP(in)) << bits;
125+
hold += (unsigned long)(*in++) << bits;
145126
bits += 8;
146127
}
147128
len += (unsigned)hold & ((1U << op) - 1);
@@ -150,9 +131,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
150131
}
151132
Tracevv((stderr, "inflate: length %u\n", len));
152133
if (bits < 15) {
153-
hold += (unsigned long)(PUP(in)) << bits;
134+
hold += (unsigned long)(*in++) << bits;
154135
bits += 8;
155-
hold += (unsigned long)(PUP(in)) << bits;
136+
hold += (unsigned long)(*in++) << bits;
156137
bits += 8;
157138
}
158139
here = dcode[hold & dmask];
@@ -165,10 +146,10 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
165146
dist = (unsigned)(here.val);
166147
op &= 15; /* number of extra bits */
167148
if (bits < op) {
168-
hold += (unsigned long)(PUP(in)) << bits;
149+
hold += (unsigned long)(*in++) << bits;
169150
bits += 8;
170151
if (bits < op) {
171-
hold += (unsigned long)(PUP(in)) << bits;
152+
hold += (unsigned long)(*in++) << bits;
172153
bits += 8;
173154
}
174155
}
@@ -196,30 +177,30 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
196177
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
197178
if (len <= op - whave) {
198179
do {
199-
PUP(out) = 0;
180+
*out++ = 0;
200181
} while (--len);
201182
continue;
202183
}
203184
len -= op - whave;
204185
do {
205-
PUP(out) = 0;
186+
*out++ = 0;
206187
} while (--op > whave);
207188
if (op == 0) {
208189
from = out - dist;
209190
do {
210-
PUP(out) = PUP(from);
191+
*out++ = *from++;
211192
} while (--len);
212193
continue;
213194
}
214195
#endif
215196
}
216-
from = window - OFF;
197+
from = window;
217198
if (wnext == 0) { /* very common case */
218199
from += wsize - op;
219200
if (op < len) { /* some from window */
220201
len -= op;
221202
do {
222-
PUP(out) = PUP(from);
203+
*out++ = *from++;
223204
} while (--op);
224205
from = out - dist; /* rest from output */
225206
}
@@ -230,14 +211,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
230211
if (op < len) { /* some from end of window */
231212
len -= op;
232213
do {
233-
PUP(out) = PUP(from);
214+
*out++ = *from++;
234215
} while (--op);
235-
from = window - OFF;
216+
from = window;
236217
if (wnext < len) { /* some from start of window */
237218
op = wnext;
238219
len -= op;
239220
do {
240-
PUP(out) = PUP(from);
221+
*out++ = *from++;
241222
} while (--op);
242223
from = out - dist; /* rest from output */
243224
}
@@ -248,35 +229,35 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
248229
if (op < len) { /* some from window */
249230
len -= op;
250231
do {
251-
PUP(out) = PUP(from);
232+
*out++ = *from++;
252233
} while (--op);
253234
from = out - dist; /* rest from output */
254235
}
255236
}
256237
while (len > 2) {
257-
PUP(out) = PUP(from);
258-
PUP(out) = PUP(from);
259-
PUP(out) = PUP(from);
238+
*out++ = *from++;
239+
*out++ = *from++;
240+
*out++ = *from++;
260241
len -= 3;
261242
}
262243
if (len) {
263-
PUP(out) = PUP(from);
244+
*out++ = *from++;
264245
if (len > 1)
265-
PUP(out) = PUP(from);
246+
*out++ = *from++;
266247
}
267248
}
268249
else {
269250
from = out - dist; /* copy direct from output */
270251
do { /* minimum length is three */
271-
PUP(out) = PUP(from);
272-
PUP(out) = PUP(from);
273-
PUP(out) = PUP(from);
252+
*out++ = *from++;
253+
*out++ = *from++;
254+
*out++ = *from++;
274255
len -= 3;
275256
} while (len > 2);
276257
if (len) {
277-
PUP(out) = PUP(from);
258+
*out++ = *from++;
278259
if (len > 1)
279-
PUP(out) = PUP(from);
260+
*out++ = *from++;
280261
}
281262
}
282263
}
@@ -313,8 +294,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
313294
hold &= (1U << bits) - 1;
314295

315296
/* update state and return */
316-
strm->next_in = in + OFF;
317-
strm->next_out = out + OFF;
297+
strm->next_in = in;
298+
strm->next_out = out;
318299
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
319300
strm->avail_out = (unsigned)(out < end ?
320301
257 + (end - out) : 257 - (out - end));

0 commit comments

Comments
 (0)