@@ -272,17 +272,20 @@ int deflate(z_stream *strm, int flush) {
272272
273273 /* If no compression wanted or very small level, just store uncompressed */
274274 if (state -> level == Z_NO_COMPRESSION ) {
275- if (strm -> avail_in > 0 ) {
276- /* Calculate block size - length fields + data */
277- uint32_t block_size = 4 + strm -> avail_in ;
275+ /* Emit one stored block per DEFLATE 64KiB limit until avail_in is drained */
276+ while (strm -> avail_in > 0 ) {
277+ uint32_t chunk = strm -> avail_in > 0xFFFF ? 0xFFFFu : strm -> avail_in ;
278+ uint32_t block_size = 4 + chunk ;
278279
279- /* Check if we have enough output space */
280+ /* Check if we have enough output space for this block's len/nlen + data */
280281 if (strm -> avail_out < block_size ) {
281282 return Z_BUF_ERROR ;
282283 }
283284
284- /* Write block header using bit buffer - final bit + type 00 (uncompressed) */
285- int ret = write_bits (strm , state , state -> is_last_block ? 1 : 0 , 1 ); /* Final block bit */
285+ /* BFINAL only on the block that drains the last of the input under Z_FINISH */
286+ int is_final = (flush == Z_FINISH && chunk == strm -> avail_in )? 1 : 0 ;
287+
288+ int ret = write_bits (strm , state , is_final , 1 ); /* Final block bit */
286289 if (ret != Z_OK ) {
287290 return ret ;
288291 }
@@ -296,7 +299,7 @@ int deflate(z_stream *strm, int flush) {
296299 flush_bits (strm , state );
297300
298301 /* Write length and inverted length */
299- uint16_t len = strm -> avail_in > 0xFFFF ? 0xFFFF : strm -> avail_in ;
302+ uint16_t len = ( uint16_t ) chunk ;
300303 * strm -> next_out ++ = len & 0xFF ;
301304 * strm -> next_out ++ = (len >> 8 ) & 0xFF ;
302305 * strm -> next_out ++ = (~len ) & 0xFF ;
@@ -305,13 +308,13 @@ int deflate(z_stream *strm, int flush) {
305308 strm -> total_out += 4 ;
306309
307310 /* Write data */
308- memcpy (strm -> next_out , strm -> next_in , len );
309- strm -> next_in += len ;
310- strm -> avail_in -= len ;
311- strm -> total_in += len ;
312- strm -> next_out += len ;
313- strm -> avail_out -= len ;
314- strm -> total_out += len ;
311+ memcpy (strm -> next_out , strm -> next_in , chunk );
312+ strm -> next_in += chunk ;
313+ strm -> avail_in -= chunk ;
314+ strm -> total_in += chunk ;
315+ strm -> next_out += chunk ;
316+ strm -> avail_out -= chunk ;
317+ strm -> total_out += chunk ;
315318 }
316319 return flush == Z_FINISH ? Z_STREAM_END : Z_OK ;
317320 }
0 commit comments