Skip to content

Commit f16b1d5

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: [standard] Fix crash when filter callback unsets StreamBucket::$data
2 parents b3cbd55 + c4a2265 commit f16b1d5

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ PHP NEWS
2727
(Weilin Du)
2828

2929
- Standard:
30+
. Fixed a segfault when a stream filter callback unsets StreamBucket::$data
31+
before re-attaching the bucket. (iliaal)
3032
. Fixed an out-of-bounds read when following a redirect response with an
3133
empty Location header. (iliaal)
3234
. Fixed read buffer compaction in php_stream_filter_flush(). (crystarm)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
unset(StreamBucket::$data) in filter callback must not crash when bucket is re-attached
3+
--FILE--
4+
<?php
5+
class MyFilter extends php_user_filter {
6+
public function filter($in, $out, &$consumed, bool $closing): int {
7+
while ($bucket = stream_bucket_make_writeable($in)) {
8+
unset($bucket->data);
9+
stream_bucket_prepend($out, $bucket);
10+
}
11+
return PSFS_PASS_ON;
12+
}
13+
}
14+
stream_filter_register("myfilter", "MyFilter");
15+
$fp = fopen("php://temp", "w+");
16+
fwrite($fp, str_repeat("A", 100));
17+
rewind($fp);
18+
stream_filter_append($fp, "myfilter");
19+
try {
20+
var_dump(stream_get_contents($fp));
21+
} catch (Throwable $e) {
22+
echo $e::class, ': ', $e->getMessage(), "\n";
23+
}
24+
echo "DONE\n";
25+
--EXPECT--
26+
Error: Typed property StreamBucket::$data must not be accessed before initialization
27+
DONE

‎ext/standard/user_filters.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,11 @@ static void php_stream_bucket_attach(int append, INTERNAL_FUNCTION_PARAMETERS)
480480
}
481481

482482
if (NULL != (pzdata = zend_read_property(NULL, Z_OBJ_P(zobject), "data", sizeof("data")-1, false, &rv))) {
483+
if (EG(exception)) {
484+
RETURN_THROWS();
485+
}
483486
ZVAL_DEREF(pzdata);
487+
ZEND_ASSERT(Z_TYPE_P(pzdata) == IS_STRING);
484488
if (!bucket->own_buf) {
485489
bucket = php_stream_bucket_make_writeable(bucket);
486490
}

0 commit comments

Comments
 (0)