diff --git a/NEWS b/NEWS index 31021de07015..cf28751877fa 100644 --- a/NEWS +++ b/NEWS @@ -61,6 +61,8 @@ PHP NEWS (Weilin Du) - Standard: + . Fixed a segfault when a stream filter callback unsets StreamBucket::$data + before re-attaching the bucket. (iliaal) . Fixed an out-of-bounds read when following a redirect response with an empty Location header. (iliaal) . Fixed a memory leak in array_merge_recursive() when the recursive merge of diff --git a/ext/standard/tests/filters/bucket_data_unset.phpt b/ext/standard/tests/filters/bucket_data_unset.phpt new file mode 100644 index 000000000000..043ea5953e92 --- /dev/null +++ b/ext/standard/tests/filters/bucket_data_unset.phpt @@ -0,0 +1,27 @@ +--TEST-- +unset(StreamBucket::$data) in filter callback must not crash when bucket is re-attached +--FILE-- +data); + stream_bucket_prepend($out, $bucket); + } + return PSFS_PASS_ON; + } +} +stream_filter_register("myfilter", "MyFilter"); +$fp = fopen("php://temp", "w+"); +fwrite($fp, str_repeat("A", 100)); +rewind($fp); +stream_filter_append($fp, "myfilter"); +try { + var_dump(stream_get_contents($fp)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +echo "DONE\n"; +--EXPECT-- +Error: Typed property StreamBucket::$data must not be accessed before initialization +DONE diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 735dd8390de8..f5e58041ca80 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -423,7 +423,11 @@ static void php_stream_bucket_attach(int append, INTERNAL_FUNCTION_PARAMETERS) } if (NULL != (pzdata = zend_read_property(NULL, Z_OBJ_P(zobject), "data", sizeof("data")-1, false, &rv))) { + if (EG(exception)) { + RETURN_THROWS(); + } ZVAL_DEREF(pzdata); + ZEND_ASSERT(Z_TYPE_P(pzdata) == IS_STRING); if (!bucket->own_buf) { bucket = php_stream_bucket_make_writeable(bucket); }