]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Change deflate_state's bi_buf from 16-bit to 32-bit.
authorNathan Moinvaziri <nathan@solidstatenetworks.com>
Sun, 2 Feb 2020 17:46:00 +0000 (09:46 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sat, 8 Feb 2020 12:53:43 +0000 (13:53 +0100)
deflate.c
deflate.h
test/fuzz/compress_fuzzer.c
trees.c

index 91f3bb8acd712e38755915adb34a9ab90a5fb586..ad2d3e7c8025d7031e0fdfe3bb21a8a032dc688d 100644 (file)
--- a/deflate.c
+++ b/deflate.c
@@ -592,14 +592,14 @@ int ZEXPORT PREFIX(deflatePrime)(PREFIX3(stream) *strm, int bits, int value) {
     if (deflateStateCheck(strm))
         return Z_STREAM_ERROR;
     s = strm->state;
-    if (bits < 0 || bits > 16 ||
-        s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
+    if (bits < 0 || bits > BIT_BUF_SIZE ||
+        s->sym_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3))
         return Z_BUF_ERROR;
     do {
-        put = Buf_size - s->bi_valid;
+        put = BIT_BUF_SIZE - s->bi_valid;
         if (put > bits)
             put = bits;
-        s->bi_buf |= (uint16_t)((value & ((1 << put) - 1)) << s->bi_valid);
+        s->bi_buf |= (uint32_t)((value & ((1 << put) - 1)) << s->bi_valid);
         s->bi_valid += put;
         zng_tr_flush_bits(s);
         value >>= put;
index f7503f10ff48a5d9f1c1ec3dc50972e1a5841d2c..8032fccba143099dcea48b8391c27a965d502973 100644 (file)
--- a/deflate.h
+++ b/deflate.h
@@ -52,7 +52,7 @@
 #define MAX_BITS 15
 /* All codes must not exceed MAX_BITS bits */
 
-#define Buf_size 16
+#define BIT_BUF_SIZE 32
 /* size of bit buffer in bi_buf */
 
 #define END_BLOCK 256
@@ -264,7 +264,7 @@ typedef struct internal_state {
     unsigned long bits_sent;      /* bit length of compressed data sent mod 2^32 */
 #endif
 
-    uint16_t bi_buf;
+    uint32_t bi_buf;
     /* Output buffer. bits are inserted starting at the bottom (least
      * significant bits).
      */
@@ -473,7 +473,7 @@ extern const unsigned char ZLIB_INTERNAL zng_dist_code[];
 #ifdef ZLIB_DEBUG
 #  define send_debug_trace(s, value, length) {\
         Tracevv((stderr, " l %2d v %4x ", length, value));\
-        Assert(length > 0 && length <= 15, "invalid length");\
+        Assert(length > 0 && length <= BIT_BUF_SIZE - 1, "invalid length");\
         s->bits_sent += (unsigned long)length;\
     }
 #else
@@ -481,20 +481,24 @@ extern const unsigned char ZLIB_INTERNAL zng_dist_code[];
 #endif
 
 /* If not enough room in bit_buf, use (valid) bits from bit_buf and
- * (16 - bit_valid) bits from value, leaving (width - (16-bit_valid))
+ * (32 - bit_valid) bits from value, leaving (width - (32-bit_valid))
  * unused bits in value.
  */
 #define send_bits(s, t_val, t_len, bit_buf, bits_valid) {\
-    int val = t_val;\
-    int len = t_len;\
+    uint32_t val = (uint32_t)t_val;\
+    uint32_t len = (uint32_t)t_len;\
     send_debug_trace(s, val, len);\
-    if (bits_valid > (int)Buf_size - len) {\
-        bit_buf |= (uint16_t)val << bits_valid;\
-        put_short(s, bit_buf);\
-        bit_buf = (uint16_t)val >> (Buf_size - bits_valid);\
-        bits_valid += len - Buf_size;\
+    if (bits_valid == BIT_BUF_SIZE) {\
+        put_uint32(s, bit_buf);\
+        bit_buf = val;\
+        bits_valid = len;\
+    } else if (bits_valid + len >= BIT_BUF_SIZE) {\
+        bit_buf |= val << bits_valid;\
+        put_uint32(s, bit_buf);\
+        bit_buf = val >> (BIT_BUF_SIZE - bits_valid);\
+        bits_valid += len - BIT_BUF_SIZE;\
     } else {\
-        bit_buf |= (uint16_t)(val) << bits_valid;\
+        bit_buf |= val << bits_valid;\
         bits_valid += len;\
     }\
 }
index 26bed106b84cc9ec87800fa3d2a9cccc09f45d76..9712e882a10005129929d598243df40e2c27e42c 100644 (file)
@@ -38,8 +38,8 @@ static void write_zlib_header(uint8_t *s) {
     header += 31 - (header % 31);
 
     /* s is guaranteed to be longer than 2 bytes. */
-    put_byte(s, 0, (unsigned char)(header >> 8));
-    put_byte(s, 1, (unsigned char)(header & 0xff));
+    put_byte(s, 0, (header >> 8));
+    put_byte(s, 1, (header & 0xff));
 }
 
 static void check_decompress(uint8_t *compr, size_t comprLen) {
diff --git a/trees.c b/trees.c
index c4d68824391cce0f4b291c100502c2c97a5fe77c..7eaaed9a68c92da5820fa9650742826788fe02e0 100644 (file)
--- a/trees.c
+++ b/trees.c
@@ -476,7 +476,7 @@ static void send_tree(deflate_state *s, ct_data *tree, int max_code) {
 
     // Temp local variables
     int filled = s->bi_valid;
-    uint16_t bit_buf = s->bi_buf;
+    uint32_t bit_buf = s->bi_buf;
 
     for (n = 0; n <= max_code; n++) {
         curlen = nextlen;
@@ -566,7 +566,7 @@ static void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes
 
     // Temp local variables
     int filled = s->bi_valid;
-    uint16_t bit_buf = s->bi_buf;
+    uint32_t bit_buf = s->bi_buf;
 
     Tracev((stderr, "\nbl counts: "));
     send_bits(s, lcodes-257, 5, bit_buf, filled); /* not +255 as stated in appnote.txt */
@@ -767,7 +767,7 @@ static void compress_block(deflate_state *s, const ct_data *ltree, const ct_data
 
     // Temp local variables
     int filled = s->bi_valid;
-    uint16_t bit_buf = s->bi_buf;
+    uint32_t bit_buf = s->bi_buf;
 
     if (s->sym_next != 0) {
         do {
@@ -869,14 +869,21 @@ ZLIB_INTERNAL unsigned bi_reverse(unsigned code, int len) {
  * Flush the bit buffer, keeping at most 7 bits in it.
  */
 static void bi_flush(deflate_state *s) {
-    if (s->bi_valid == 16) {
-        put_short(s, s->bi_buf);
+    if (s->bi_valid == 32) {
+        put_uint32(s, s->bi_buf);
         s->bi_buf = 0;
         s->bi_valid = 0;
-    } else if (s->bi_valid >= 8) {
-        put_byte(s, (unsigned char)s->bi_buf);
-        s->bi_buf >>= 8;
-        s->bi_valid -= 8;
+    } else {
+        if (s->bi_valid >= 16) {
+            put_short(s, s->bi_buf);
+            s->bi_buf >>= 16;
+            s->bi_valid -= 16;
+        }
+        if (s->bi_valid >= 8) {
+            put_byte(s, s->bi_buf);
+            s->bi_buf >>= 8;
+            s->bi_valid -= 8;
+        }
     }
 }
 
@@ -884,10 +891,17 @@ static void bi_flush(deflate_state *s) {
  * Flush the bit buffer and align the output on a byte boundary
  */
 ZLIB_INTERNAL void bi_windup(deflate_state *s) {
-    if (s->bi_valid > 8) {
-        put_short(s, s->bi_buf);
-    } else if (s->bi_valid > 0) {
-        put_byte(s, (unsigned char)s->bi_buf);
+    if (s->bi_valid > 24) {
+        put_uint32(s, s->bi_buf);
+    } else {
+        if (s->bi_valid > 8) {
+            put_short(s, s->bi_buf);
+            s->bi_buf >>= 16;
+            s->bi_valid -= 16;
+        }
+        if (s->bi_valid > 0) {
+            put_byte(s, s->bi_buf);
+        }
     }
     s->bi_buf = 0;
     s->bi_valid = 0;