]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Fixed avail_out == 0 conditional not returning need_more in deflate_quick.
authorNathan Moinvaziri <nathan@nathanm.com>
Fri, 26 Jun 2020 05:52:59 +0000 (22:52 -0700)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sun, 28 Jun 2020 09:17:44 +0000 (11:17 +0200)
Fixed ending block when returning need_more caused problems with inflate.

So instead of ending the block each time the function returns to finish the last block, we check upon start to see if it is the last block and if the last block has been started, and if not it will close the previous block and start the last block.

deflate_quick.c

index ad1dc2ea0d42ed62e8650ae91ceb1c17aa9980c2..3e47f2be00f442cfa7b1179d7c6da22ecb331e48 100644 (file)
@@ -28,7 +28,7 @@ extern const ct_data static_dtree[D_CODES];
 
 #define QUICK_START_BLOCK(s, last) { \
     zng_tr_emit_tree(s, STATIC_TREES, last); \
-    s->block_open = 1; \
+    s->block_open = 1 + last; \
     s->block_start = s->strstart; \
 }
 
@@ -45,10 +45,15 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
     unsigned dist, match_len, last;
 
 
-    if (s->block_open == 0 && s->lookahead > 0) {
+    last = (flush == Z_FINISH) ? 1 : 0;
+    if (last && s->block_open != 2) {
+        /* Emit end of previous block */
+        QUICK_END_BLOCK(s, 0);
+        /* Emit start of last block */
+        QUICK_START_BLOCK(s, last);
+    } else if (s->block_open == 0 && s->lookahead > 0) {
         /* Start new block only when we have lookahead data, so that if no
            input data is given an empty block will not be written */
-        last = (flush == Z_FINISH) ? 1 : 0;
         QUICK_START_BLOCK(s, last);
     }
 
@@ -56,17 +61,13 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
         if (s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size) {
             flush_pending(s->strm);
             if (s->strm->avail_out == 0 && flush != Z_FINISH) {
-                /* Break to emit end block and return need_more */
-                break;
+                return need_more;
             }
         }
 
         if (s->lookahead < MIN_LOOKAHEAD) {
             fill_window(s);
             if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-                /* Always emit end block, in case next call is with Z_FINISH,
-                   and we need to emit start of last block */
-                QUICK_END_BLOCK(s, 0);
                 return need_more;
             }
             if (s->lookahead == 0)
@@ -75,7 +76,6 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
             if (s->block_open == 0) {
                 /* Start new block when we have lookahead data, so that if no
                    input data is given an empty block will not be written */
-                last = (flush == Z_FINISH) ? 1 : 0;
                 QUICK_START_BLOCK(s, last);
             }
         }
@@ -108,7 +108,6 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
 
     s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
 
-    last = (flush == Z_FINISH) ? 1 : 0;
     QUICK_END_BLOCK(s, last);
     flush_pending(s->strm);