Skip to content

Commit c4a2265

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

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
@@ -63,6 +63,8 @@ PHP NEWS
6363
(Weilin Du)
6464

6565
- Standard:
66+
. Fixed a segfault when a stream filter callback unsets StreamBucket::$data
67+
before re-attaching the bucket. (iliaal)
6668
. Fixed an out-of-bounds read when following a redirect response with an
6769
empty Location header. (iliaal)
6870
. 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
@@ -419,7 +419,11 @@ static void php_stream_bucket_attach(int append, INTERNAL_FUNCTION_PARAMETERS)
419419
}
420420

421421
if (NULL != (pzdata = zend_read_property(NULL, Z_OBJ_P(zobject), "data", sizeof("data")-1, false, &rv))) {
422+
if (EG(exception)) {
423+
RETURN_THROWS();
424+
}
422425
ZVAL_DEREF(pzdata);
426+
ZEND_ASSERT(Z_TYPE_P(pzdata) == IS_STRING);
423427
if (!bucket->own_buf) {
424428
bucket = php_stream_bucket_make_writeable(bucket);
425429
}

0 commit comments

Comments
 (0)