summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorGreg Beaver <cellog@php.net>2008-01-12 21:28:48 +0000
committerGreg Beaver <cellog@php.net>2008-01-12 21:28:48 +0000
commit79abe24b1b650b6787554caf29676e093ba4086f (patch)
tree8cd1b14226fb13d3d1a4eec471565938c7e582ec /ext
parent7c1952c8637d66758d7fa3ffc55e93afca31636d (diff)
downloadphp-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.c14
-rw-r--r--ext/zlib/tests/bug.tarbin0 -> 4720640 bytes
-rw-r--r--ext/zlib/tests/bug_40189.phpt21
-rw-r--r--ext/zlib/tests/bug_40189_2.phpt14
-rw-r--r--ext/zlib/zlib_filter.c19
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
new file mode 100644
index 0000000000..77fd77832f
--- /dev/null
+++ b/ext/zlib/tests/bug.tar
Binary files differ
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;