From 02b271b351214ad15b40323ad073081225c9a4c4 Mon Sep 17 00:00:00 2001 From: NickSdot Date: Tue, 25 Aug 2026 00:18:57 +0700 Subject: [PATCH] tests: filter bucket leaks skip/warn --- ...er_class_coerce_consumed_by_ref_param.phpt | 27 ++++++- ...eam_filter_register_mock_class_filter.phpt | 27 ++++++- ...m_filter_register_unprocessed_buckets.phpt | 80 +++++++++++++++++++ ...egister_unprocessed_buckets_reentrant.phpt | 68 ++++++++++++++++ 4 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 ext/standard/tests/filters/stream_filter_register_unprocessed_buckets.phpt create mode 100644 ext/standard/tests/filters/stream_filter_register_unprocessed_buckets_reentrant.phpt 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..78932a132ef3 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,30 @@ --TEST-- stream_filter_register() with a class that coerces the $consumed parameter of filter method ---XFAIL-- -This leaks memory +--SKIPIF-- + --FILE-- --FILE-- +--FILE-- +emitted) { + $this->emitted = true; + $bucket = stream_bucket_new($this->stream, "x"); + stream_bucket_append($out, $bucket); + } + + return PSFS_ERR_FATAL; + } +} + +stream_filter_register("test.feed", FeedFilter::class); + +$stream = fopen("php://memory", "w+"); +fwrite($stream, "x\nabcdef"); +rewind($stream); + +var_dump(fgets($stream)); +var_dump(stream_filter_append($stream, "test.feed", STREAM_FILTER_READ)); +fclose($stream); + +stream_filter_register("test.fatal", FatalFilter::class); + +$stream = fopen("php://memory", "w+"); +$filter = stream_filter_append($stream, "test.fatal", STREAM_FILTER_WRITE); + +var_dump(stream_filter_remove($filter)); +fclose($stream); + +?> +--EXPECTF-- +string(2) "x +" + +Warning: stream_filter_append(): Unprocessed filter buckets remaining on input brigade in %s on line %d +resource(%d) of type (stream filter) + +Warning: stream_filter_remove(): Unable to flush filter, not removing in %s on line %d +bool(false) diff --git a/ext/standard/tests/filters/stream_filter_register_unprocessed_buckets_reentrant.phpt b/ext/standard/tests/filters/stream_filter_register_unprocessed_buckets_reentrant.phpt new file mode 100644 index 000000000000..cb17993bd2da --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_unprocessed_buckets_reentrant.phpt @@ -0,0 +1,68 @@ +--TEST-- +stream_filter_register() with a class whose input brigade is modified by a warning handler +--SKIPIF-- + +--FILE-- +firstCall) { + $this->firstCall = false; + $GLOBALS['brigade'] = $in; + $GLOBALS['bucket'] = stream_bucket_new($this->stream, 'refilled'); + } + + return PSFS_PASS_ON; + } +} + +stream_filter_register('test.reentrant', ReentrantFilter::class); + +set_error_handler(static function (int $severity, string $message): bool +{ + if (str_contains($message, 'Unprocessed filter buckets')) { + stream_bucket_append($GLOBALS['brigade'], $GLOBALS['bucket']); + echo "Handled warning\n"; + return true; + } + + return false; +}); + +$stream = fopen('php://memory', 'w+'); +stream_filter_append($stream, 'test.reentrant', STREAM_FILTER_WRITE); + +var_dump(fwrite($stream, 'input')); +fclose($stream); + +?> +--EXPECT-- +Handled warning +int(0)