[php-src] master: Merge branch 'PHP-8.5'

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-08-27T17:10:26-04:00

Commit: https://github.com/php/php-src/commit/f16b1d5d25a6ed9c03b11f09433e822dbda909a0
Raw diff: https://github.com/php/php-src/commit/f16b1d5d25a6ed9c03b11f09433e822dbda909a0.diff

Merge branch 'PHP-8.5'

* PHP-8.5:
  [standard] Fix crash when filter callback unsets StreamBucket::$data

Changed paths:
  A  ext/standard/tests/filters/bucket_data_unset.phpt
  M  NEWS
  M  ext/standard/user_filters.c


Diff:

diff --git a/NEWS b/NEWS
index df78bf6abe8a..500f75cc050d 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,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 read buffer compaction in php_stream_filter_flush(). (crystarm)
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--
+<?php
+class MyFilter extends php_user_filter {
+    public function filter($in, $out, &$consumed, bool $closing): int {
+        while ($bucket = stream_bucket_make_writeable($in)) {
+            unset($bucket->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 e65ddd78ba4d..b699c12ed9ba 100644
--- a/ext/standard/user_filters.c
+++ b/ext/standard/user_filters.c
@@ -480,7 +480,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);
 		}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.