diff options
author | Greg Beaver <cellog@php.net> | 2008-01-12 21:28:48 +0000 |
---|---|---|
committer | Greg Beaver <cellog@php.net> | 2008-01-12 21:28:48 +0000 |
commit | 79abe24b1b650b6787554caf29676e093ba4086f (patch) | |
tree | 8cd1b14226fb13d3d1a4eec471565938c7e582ec /ext | |
parent | 7c1952c8637d66758d7fa3ffc55e93afca31636d (diff) | |
download | php-git-79abe24b1b650b6787554caf29676e093ba4086f.tar.gz |
MFH: fix faulty fix for Bug #40189, and provide real fix for the bug
Diffstat (limited to 'ext')
-rw-r--r-- | ext/bz2/bz2_filter.c | 14 | ||||
-rw-r--r-- | ext/zlib/tests/bug.tar | bin | 0 -> 4720640 bytes | |||
-rw-r--r-- | ext/zlib/tests/bug_40189.phpt | 21 | ||||
-rw-r--r-- | ext/zlib/tests/bug_40189_2.phpt | 14 | ||||
-rw-r--r-- | ext/zlib/zlib_filter.c | 19 |
5 files changed, 51 insertions, 17 deletions
diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c index fe4a11f585..c8fc59ef2f 100644 --- a/ext/bz2/bz2_filter.c +++ b/ext/bz2/bz2_filter.c @@ -101,12 +101,7 @@ static php_stream_filter_status_t php_bz2_decompress_filter( consumed += desired; bin += desired; - if (!desired) { - flags |= PSFS_FLAG_FLUSH_CLOSE; - break; - } - - if (data->strm.avail_out < data->outbuf_len) { + if (status == BZ_STREAM_END || data->strm.avail_out < data->outbuf_len) { php_stream_bucket *out_bucket; size_t bucketlen = data->outbuf_len - data->strm.avail_out; out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC); @@ -114,6 +109,13 @@ static php_stream_filter_status_t php_bz2_decompress_filter( data->strm.avail_out = data->outbuf_len; data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; + if (status == BZ_STREAM_END) { + /* no more data to decompress, and nothing was spat out */ + if (data->strm.avail_out >= data->outbuf_len) { + php_stream_bucket_delref(bucket TSRMLS_CC); + } + return PSFS_PASS_ON; + } } } php_stream_bucket_delref(bucket TSRMLS_CC); diff --git a/ext/zlib/tests/bug.tar b/ext/zlib/tests/bug.tar Binary files differnew file mode 100644 index 0000000000..77fd77832f --- /dev/null +++ b/ext/zlib/tests/bug.tar diff --git a/ext/zlib/tests/bug_40189.phpt b/ext/zlib/tests/bug_40189.phpt new file mode 100644 index 0000000000..5ae51bf4ba --- /dev/null +++ b/ext/zlib/tests/bug_40189.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #40189 (endless loop in zlib.inflate stream filter) +--SKIPIF-- +<?php if (!extension_loaded("zlib")) print "skip"; ?> +--FILE-- +<?php +// this string is an excerpt of a phar archive that caused an infinite loop +$a = "\x3\x0\x85\x46\x2f\x7c\xc2\xaa\x69\x2b\x6d\xe5\xdb\xfe\xe4\x21\x8f\x0\x97\x21\x1d\x2\x0\x0\x0\x47\x42\x4d\x42"; +var_dump(base64_encode($a)); +$gp = fopen('test.other', 'wb'); +$fp = fopen('data://text/plain;base64,AwCFRi98wqppK23l2/7kIY8AlyEdAgAAAEdCTUI=', 'r'); +stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_READ); +var_dump(stream_copy_to_stream($fp, $gp, 5)); +fclose($fp); +fclose($gp); +var_dump(file_get_contents('test.other')); +?> +--EXPECT-- +string(40) "AwCFRi98wqppK23l2/7kIY8AlyEdAgAAAEdCTUI=" +int(0) +string(0) "" diff --git a/ext/zlib/tests/bug_40189_2.phpt b/ext/zlib/tests/bug_40189_2.phpt new file mode 100644 index 0000000000..d89ffea8bc --- /dev/null +++ b/ext/zlib/tests/bug_40189_2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #40189 (test for truncated deflate, also part of erroneous fix for #40189) +--SKIPIF-- +<?php if (!extension_loaded("zlib")) print "skip"; ?> +--FILE-- +<?php +$a = fopen('ext/zlib/tests/bug.tar', 'rb'); +stream_filter_append($a, 'zlib.deflate', STREAM_FILTER_READ, array('window' => 15+16)); +$b = fread($a, 4716032); +var_dump(strlen($b)); +// when broken, this outputs "int(686904)" +?> +--EXPECT-- +int(1676116)
\ No newline at end of file diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c index 976c04d432..80359498ec 100644 --- a/ext/zlib/zlib_filter.c +++ b/ext/zlib/zlib_filter.c @@ -100,12 +100,7 @@ static php_stream_filter_status_t php_zlib_inflate_filter( consumed += desired; bin += desired; - if (!desired) { - flags |= PSFS_FLAG_FLUSH_CLOSE; - break; - } - - if (data->strm.avail_out < data->outbuf_len) { + if (status == Z_STREAM_END || data->strm.avail_out < data->outbuf_len) { php_stream_bucket *out_bucket; size_t bucketlen = data->outbuf_len - data->strm.avail_out; out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC); @@ -113,6 +108,13 @@ static php_stream_filter_status_t php_zlib_inflate_filter( data->strm.avail_out = data->outbuf_len; data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; + if (status == Z_STREAM_END) { + /* no more data to decompress, and nothing was spat out */ + if (data->strm.avail_out >= data->outbuf_len) { + php_stream_bucket_delref(bucket TSRMLS_CC); + } + return PSFS_PASS_ON; + } } } php_stream_bucket_delref(bucket TSRMLS_CC); @@ -213,11 +215,6 @@ static php_stream_filter_status_t php_zlib_deflate_filter( consumed += desired; bin += desired; - if (!desired) { - flags |= PSFS_FLAG_FLUSH_CLOSE; - break; - } - if (data->strm.avail_out < data->outbuf_len) { php_stream_bucket *out_bucket; size_t bucketlen = data->outbuf_len - data->strm.avail_out; |