From 2fb381542d18ae4e24c2d42fb6ac7467e63216e0 Mon Sep 17 00:00:00 2001 From: Matthias Goergens Date: Fri, 31 Jul 2026 20:59:31 +0800 Subject: [PATCH] Fix leaks from unprocessed user filter buckets --- NEWS | 4 ++++ ...ilter_register_class_coerce_consumed_by_ref_param.phpt | 2 -- .../stream_filter_register_filter_always_feed.phpt | 8 ++++++++ .../filters/stream_filter_register_mock_class_filter.phpt | 2 -- ext/standard/user_filters.c | 5 +++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 4364d69650e5..53f2d0212a79 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,10 @@ PHP NEWS is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), file_exists(), lstat(), stat(). (Girgias) +- Streams: + . Fixed memory leaks when a user stream filter returns PSFS_PASS_ON without + processing all input buckets. (Matthias Goergens) + 30 Jul 2026, PHP 8.6.0alpha3 - Core: diff --git a/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt b/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt index f5f0ecca7975..6133cc2c7759 100644 --- a/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt +++ b/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt @@ -1,7 +1,5 @@ --TEST-- stream_filter_register() with a class that coerces the $consumed parameter of filter method ---XFAIL-- -This leaks memory --FILE-- --EXPECTF-- bool(true) @@ -22,3 +26,7 @@ resource(4) of type (stream filter) Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d int(0) +resource(%d) of type (stream filter) + +Warning: stream_get_contents(): Unprocessed filter buckets remaining on input brigade in %s on line %d +string(0) "" diff --git a/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt b/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt index 4d2309a718eb..71fcd7f0d2e3 100644 --- a/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt +++ b/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt @@ -1,7 +1,5 @@ --TEST-- stream_filter_register() with a class name exist that mocks php_user_filter with a filter method ---XFAIL-- -This leaks memory --FILE-- head) { php_error_docref(NULL, E_WARNING, "Unprocessed filter buckets remaining on input brigade"); + php_stream_bucket *bucket; + while ((bucket = buckets_in->head)) { + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); + } } /* filter resources are cleaned up by the stream destructor,