From: Jani Taskinen Date: Wed, 9 Dec 2009 17:47:38 +0000 (+0000) Subject: - Fixed BC problem in new zlib implementation: truncated (invalid) short data was... X-Git-Tag: php-5.4.0alpha1~191^2~2261 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8d07fcf017b28f28650ce9ee733a6f797d2a9375;p=php - Fixed BC problem in new zlib implementation: truncated (invalid) short data was not caught --- diff --git a/ext/zlib/tests/006.phpt b/ext/zlib/tests/006.phpt index 95b989b307..3ac73b1419 100644 --- a/ext/zlib/tests/006.phpt +++ b/ext/zlib/tests/006.phpt @@ -31,7 +31,6 @@ var_dump(gzinflate($data1)); var_dump(gzinflate($data2)); $data2[4] = 0; var_dump(gzinflate((binary)$data2)); - echo "Done\n"; ?> --EXPECTF-- @@ -57,8 +56,12 @@ bool(false) Warning: gzinflate(): length (-1) must be greater or equal zero in %s on line %d bool(false) -string(0) "" -string(0) "" + +Warning: gzinflate(): data error in %s on line %d +bool(false) + +Warning: gzinflate(): data error in %s on line %d +bool(false) string(94) "Answer me, it can't be so hard Cry to relieve what's in your heart Desolation, grief and agony" diff --git a/ext/zlib/tests/gzinflate-bug42663.phpt b/ext/zlib/tests/gzinflate-bug42663.phpt index dd53c78f4e..2d1eba3725 100644 --- a/ext/zlib/tests/gzinflate-bug42663.phpt +++ b/ext/zlib/tests/gzinflate-bug42663.phpt @@ -15,9 +15,12 @@ var_dump(strlen($deflated)); $truncated = substr($deflated, 0, 65535); var_dump(strlen($truncated)); // inflate $truncated string (check if it will not eat all memory) -gzinflate($truncated); +var_dump(gzinflate($truncated)); ?> ---EXPECT-- +--EXPECTF-- int(168890) int(66743) int(65535) + +Warning: gzinflate(): data error in %s on line %d +bool(false) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 039577bac1..1a77f022cf 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -344,15 +344,19 @@ static inline int php_zlib_inflate_rounds(z_stream *Z, size_t max, char **buf, s } } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < 100); - if (status == Z_OK || status == Z_STREAM_END) { + if (status == Z_STREAM_END) { buffer.data = erealloc(buffer.data, buffer.used + 1); buffer.data[buffer.used] = '\0'; *buf = buffer.data; *len = buffer.used; - } else if (buffer.data) { - efree(buffer.data); + } else { + if (buffer.data) { + efree(buffer.data); + } + /* HACK: See zlib/examples/zpipe.c inf() function for explanation. */ + /* This works as long as this function is not used for streaming. Required to catch very short invalid data. */ + status = (status == Z_OK) ? Z_DATA_ERROR : status; } - return status; } /* }}} */ @@ -375,7 +379,6 @@ retry_raw_inflate: Z.avail_in = in_len; switch (status = php_zlib_inflate_rounds(&Z, max_len, out_buf, out_len)) { - case Z_OK: case Z_STREAM_END: inflateEnd(&Z); return SUCCESS;