diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug78406.phpt | 44 | ||||
-rw-r--r-- | main/main.c | 12 |
3 files changed, 56 insertions, 2 deletions
@@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug #78396 (Second file_put_contents in Shutdown hangs script). (Nikita) + . Fixed bug #78406 (Broken file includes with user-defined stream filters). + (Nikita) - Date: . Fixed bug #78383 (Casting a DateTime to array no longer returns its diff --git a/Zend/tests/bug78406.phpt b/Zend/tests/bug78406.phpt new file mode 100644 index 0000000000..64fd2a1945 --- /dev/null +++ b/Zend/tests/bug78406.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #78406: Broken file includes with user-defined stream filters +--FILE-- +<?php + +echo "bug\n"; // Should be transformed by filter on second include + +if (!class_exists(SampleFilter::class)) { + class SampleFilter extends php_user_filter + { + private $data = ''; + + public function filter($in, $out, &$consumed, $closing) + { + while ($bucket = stream_bucket_make_writeable($in)) + { + $this->data .= $bucket->data; + } + + if ($closing || feof($this->stream)) + { + $consumed = strlen($this->data); + + $this->data = str_replace('bug', 'feature', $this->data); + + $bucket = stream_bucket_new($this->stream, $this->data); + stream_bucket_append($out, $bucket); + + return PSFS_PASS_ON; + } + + return PSFS_FEED_ME; + } + } + stream_filter_register('sample.filter', SampleFilter::class); + $uri = 'php://filter/read=sample.filter/resource='. __FILE__; + + include $uri; // We expect one more "feature" output at line 3 +} + +?> +--EXPECT-- +bug +feature diff --git a/main/main.c b/main/main.c index 5822cbfa21..d865027887 100644 --- a/main/main.c +++ b/main/main.c @@ -1564,8 +1564,16 @@ static void php_zend_stream_closer(void *handle) /* {{{ */ static size_t php_zend_stream_fsizer(void *handle) /* {{{ */ { - php_stream_statbuf ssb; - if (php_stream_stat((php_stream*)handle, &ssb) == 0) { + php_stream *stream = handle; + php_stream_statbuf ssb; + + /* File size reported by stat() may be inaccurate if stream filters are used. + * TODO: Should stat() be generally disabled if filters are used? */ + if (stream->readfilters.head) { + return 0; + } + + if (php_stream_stat(stream, &ssb) == 0) { return ssb.sb.st_size; } return 0; |