Skip to content

Commit b01824e

Browse files
committed
Fixed bug #78406
1 parent bdf3fa8 commit b01824e

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ PHP NEWS
55
- Core:
66
. Fixed bug #78396 (Second file_put_contents in Shutdown hangs script).
77
(Nikita)
8+
. Fixed bug #78406 (Broken file includes with user-defined stream filters).
9+
(Nikita)
810

911
- Date:
1012
. Fixed bug #78383 (Casting a DateTime to array no longer returns its

Zend/tests/bug78406.phpt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Bug #78406: Broken file includes with user-defined stream filters
3+
--FILE--
4+
<?php
5+
6+
echo "bug\n"; // Should be transformed by filter on second include
7+
8+
if (!class_exists(SampleFilter::class)) {
9+
class SampleFilter extends php_user_filter
10+
{
11+
private $data = '';
12+
13+
public function filter($in, $out, &$consumed, $closing)
14+
{
15+
while ($bucket = stream_bucket_make_writeable($in))
16+
{
17+
$this->data .= $bucket->data;
18+
}
19+
20+
if ($closing || feof($this->stream))
21+
{
22+
$consumed = strlen($this->data);
23+
24+
$this->data = str_replace('bug', 'feature', $this->data);
25+
26+
$bucket = stream_bucket_new($this->stream, $this->data);
27+
stream_bucket_append($out, $bucket);
28+
29+
return PSFS_PASS_ON;
30+
}
31+
32+
return PSFS_FEED_ME;
33+
}
34+
}
35+
stream_filter_register('sample.filter', SampleFilter::class);
36+
$uri = 'php://filter/read=sample.filter/resource='. __FILE__;
37+
38+
include $uri; // We expect one more "feature" output at line 3
39+
}
40+
41+
?>
42+
--EXPECT--
43+
bug
44+
feature

main/main.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,8 +1564,16 @@ static void php_zend_stream_closer(void *handle) /* {{{ */
15641564

15651565
static size_t php_zend_stream_fsizer(void *handle) /* {{{ */
15661566
{
1567-
php_stream_statbuf ssb;
1568-
if (php_stream_stat((php_stream*)handle, &ssb) == 0) {
1567+
php_stream *stream = handle;
1568+
php_stream_statbuf ssb;
1569+
1570+
/* File size reported by stat() may be inaccurate if stream filters are used.
1571+
* TODO: Should stat() be generally disabled if filters are used? */
1572+
if (stream->readfilters.head) {
1573+
return 0;
1574+
}
1575+
1576+
if (php_stream_stat(stream, &ssb) == 0) {
15691577
return ssb.sb.st_size;
15701578
}
15711579
return 0;

0 commit comments

Comments
 (0)