]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Use post-increment only in inffast.c.
authorMark Adler <madler@alumni.caltech.edu>
Thu, 22 Sep 2016 05:25:21 +0000 (22:25 -0700)
committerHans Kristian Rosbach <hk-git@circlestorm.org>
Tue, 31 Jan 2017 10:06:20 +0000 (11:06 +0100)
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.

inffast.c

index 8acb261d008f7fe324044d183cfd388c48d23e9c..50ec86ef47e1073bc631a679acdeb1ea6972457e 100644 (file)
--- a/inffast.c
+++ b/inffast.c
@@ -8,25 +8,6 @@
 #include "inflate.h"
 #include "inffast.h"
 
-/* Allow machine dependent optimization for post-increment or pre-increment.
-   Based on testing to date,
-   Pre-increment preferred for:
-   - PowerPC G3 (Adler)
-   - MIPS R5000 (Randers-Pehrson)
-   Post-increment preferred for:
-   - none
-   No measurable difference:
-   - Pentium III (Anderson)
-   - M68060 (Nikl)
- */
-#ifdef POSTINC
-#  define OFF 0
-#  define PUP(a) *(a)++
-#else
-#  define OFF 1
-#  define PUP(a) *++(a)
-#endif
-
 /* Return the low n bits of the bit accumulator (n < 16) */
 #define BITS(n) \
     (hold & ((1U << (n)) - 1))
@@ -103,9 +84,9 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
 
     /* copy state to local variables */
     state = (struct inflate_state *)strm->state;
-    in = strm->next_in - OFF;
+    in = strm->next_in;
     last = in + (strm->avail_in - 5);
-    out = strm->next_out - OFF;
+    out = strm->next_out;
     beg = out - (start - strm->avail_out);
     end = out + (strm->avail_out - 257);
 #ifdef INFLATE_STRICT
@@ -126,9 +107,9 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
        input data or output space */
     do {
         if (bits < 15) {
-            hold += (PUP(in) << bits);
+            hold += (uint32_t)(*in++) << bits;
             bits += 8;
-            hold += (PUP(in) << bits);
+            hold += (uint32_t)(*in++) << bits;
             bits += 8;
         }
         here = lcode[hold & lmask];
@@ -139,13 +120,13 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
             Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
                     "inflate:         literal '%c'\n" :
                     "inflate:         literal 0x%02x\n", here.val));
-            PUP(out) = (unsigned char)(here.val);
+            *out++ = (unsigned char)(here.val);
         } else if (op & 16) {                     /* length base */
             len = here.val;
             op &= 15;                           /* number of extra bits */
             if (op) {
                 if (bits < op) {
-                    hold += (PUP(in) << bits);
+                    hold += (uint32_t)(*in++) << bits;
                     bits += 8;
                 }
                 len += BITS(op);
@@ -153,9 +134,9 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
             }
             Tracevv((stderr, "inflate:         length %u\n", len));
             if (bits < 15) {
-                hold += (PUP(in) << bits);
+                hold += (uint32_t)(*in++) << bits;
                 bits += 8;
-                hold += (PUP(in) << bits);
+                hold += (uint32_t)(*in++) << bits;
                 bits += 8;
             }
             here = dcode[hold & dmask];
@@ -166,10 +147,10 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
                 dist = here.val;
                 op &= 15;                       /* number of extra bits */
                 if (bits < op) {
-                    hold += (PUP(in) << bits);
+                    hold += (uint32_t)(*in++) << bits;
                     bits += 8;
                     if (bits < op) {
-                        hold += (PUP(in) << bits);
+                        hold += (uint32_t)(*in++) << bits;
                         bits += 8;
                     }
                 }
@@ -195,30 +176,30 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
                         if (len <= op - whave) {
                             do {
-                                PUP(out) = 0;
+                                *out++ = 0;
                             } while (--len);
                             continue;
                         }
                         len -= op - whave;
                         do {
-                            PUP(out) = 0;
+                            *out++ = 0;
                         } while (--op > whave);
                         if (op == 0) {
                             from = out - dist;
                             do {
-                                PUP(out) = PUP(from);
+                                *out++ = *from++;
                             } while (--len);
                             continue;
                         }
 #endif
                     }
-                    from = window - OFF;
+                    from = window;
                     if (wnext == 0) {           /* very common case */
                         from += wsize - op;
                         if (op < len) {         /* some from window */
                             len -= op;
                             do {
-                                PUP(out) = PUP(from);
+                                *out++ = *from++;
                             } while (--op);
                             from = out - dist;  /* rest from output */
                         }
@@ -228,14 +209,14 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
                         if (op < len) {         /* some from end of window */
                             len -= op;
                             do {
-                                PUP(out) = PUP(from);
+                                *out++ = *from++;
                             } while (--op);
-                            from = window - OFF;
+                            from = window;
                             if (wnext < len) {  /* some from start of window */
                                 op = wnext;
                                 len -= op;
                                 do {
-                                    PUP(out) = PUP(from);
+                                    *out++ = *from++;
                                 } while (--op);
                                 from = out - dist;      /* rest from output */
                             }
@@ -245,34 +226,34 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
                         if (op < len) {         /* some from window */
                             len -= op;
                             do {
-                                PUP(out) = PUP(from);
+                                *out++ = *from++;
                             } while (--op);
                             from = out - dist;  /* rest from output */
                         }
                     }
                     while (len > 2) {
-                        PUP(out) = PUP(from);
-                        PUP(out) = PUP(from);
-                        PUP(out) = PUP(from);
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        *out++ = *from++;
                         len -= 3;
                     }
                     if (len) {
-                        PUP(out) = PUP(from);
+                        *out++ = *from++;
                         if (len > 1)
-                            PUP(out) = PUP(from);
+                            *out++ = *from++;
                     }
                 } else {
                     from = out - dist;          /* copy direct from output */
                     do {                        /* minimum length is three */
-                        PUP(out) = PUP(from);
-                        PUP(out) = PUP(from);
-                        PUP(out) = PUP(from);
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        *out++ = *from++;
                         len -= 3;
                     } while (len > 2);
                     if (len) {
-                        PUP(out) = PUP(from);
+                        *out++ = *from++;
                         if (len > 1)
-                            PUP(out) = PUP(from);
+                            *out++ = *from++;
                     }
                 }
             } else if ((op & 64) == 0) {          /* 2nd level distance code */
@@ -304,8 +285,8 @@ void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) {
     hold &= (1U << bits) - 1;
 
     /* update state and return */
-    strm->next_in = in + OFF;
-    strm->next_out = out + OFF;
+    strm->next_in = in;
+    strm->next_out = out;
     strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
     strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end));
     state->hold = hold;