From: Mark Adler Date: Wed, 23 Nov 2016 07:29:19 +0000 (-0800) Subject: Assure that deflateParams() will not switch functions mid-block. X-Git-Tag: 1.9.9-b1~722 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e84a42f7a34c7f8728d669a747d149907ec9818c;p=thirdparty%2Fzlib-ng.git Assure that deflateParams() will not switch functions mid-block. This alters the specification in zlib.h, so that deflateParams() will not change any parameters if there is not enough output space in the event that a block is emitted in order to allow switching the compression function. --- diff --git a/deflate.c b/deflate.c index 662d0294b..2d03dd24e 100644 --- a/deflate.c +++ b/deflate.c @@ -446,7 +446,6 @@ int ZEXPORT deflatePrime(z_stream *strm, int bits, int value) { int ZEXPORT deflateParams(z_stream *strm, int level, int strategy) { deflate_state *s; compress_func func; - int err = Z_OK; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -461,9 +460,11 @@ int ZEXPORT deflateParams(z_stream *strm, int level, int strategy) { if ((strategy != s->strategy || func != configuration_table[level].func)) { /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - if (err == Z_BUF_ERROR && s->pending == 0) - err = Z_OK; + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_out == 0) + return Z_BUF_ERROR; } if (s->level != level) { s->level = level; @@ -473,7 +474,7 @@ int ZEXPORT deflateParams(z_stream *strm, int level, int strategy) { s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; - return err; + return Z_OK; } /* ========================================================================= */ diff --git a/zlib.h b/zlib.h index 73b5624e7..24c755811 100644 --- a/zlib.h +++ b/zlib.h @@ -689,24 +689,25 @@ ZEXTERN int ZEXPORT deflateParams(z_stream *strm, int level, int strategy); new level and strategy will take effect at the next call of deflate(). If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will - take effect at an undetermined location in the uncompressed data provided so - far. In order to assure a change in the parameters at a specific location - in the uncompressed data, the deflate stream should first be flushed with - Z_BLOCK or another flush parameter, and deflate() called until - strm.avail_out is not zero, before the call of deflateParams(). Then no - more input data should be provided before the deflateParams() call. If this - is done, the old level and strategy will be applied to the data compressed - before deflateParams(), and the new level and strategy will be applied to - the the data compressed after deflateParams(). - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression before the - parameters were changed. Note that in the case of a Z_BUF_ERROR, the - parameters are changed nevertheless, and will take effect at an undetermined - location in the previously supplied uncompressed data. Compression may - proceed after a Z_BUF_ERROR. + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. */ ZEXTERN int ZEXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain);