Skip to content

Fix leaks and data loss when user filter leaves buckets on input brigade - #24146

Closed
bukka wants to merge 1 commit into
php:PHP-8.4from
bukka:stream_filter_user_unconsumed_buckets
Closed

bukka wants to merge 1 commit into
php:PHP-8.4from
bukka:stream_filter_user_unconsumed_buckets

Conversation

@bukka

@bukka bukka commented Oct 5, 2026

Copy link
Copy Markdown
Member

The callers expect the input brigade to be empty when the filter returns, so buckets left on it leaked. Buckets put back with PSFS_FEED_ME to be seen again with the next data are now kept by the user filter and prepended to its input on the next call, which also fixes them aliasing the read chunk buffer, being re-filtered by preceding filters in a chain and being lost on the write path. Leftover buckets on any other status, or on the closing call, are released with the existing warning.

This is alternative to #20058

@Truta446

Copy link
Copy Markdown
Contributor

Two things I noticed while testing this on PHP-8.4 with tests from master: ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt and stream_filter_register_class_coerce_consumed_by_ref_param.phpt (master only, --XFAIL-- This leaks memory) pass with this patch, so their XFAIL sections should be dropped when merging up. And the reentrant case from #23440 (an error handler that appends a bucket to $in while handling the "Unprocessed filter buckets" warning) still leaks 2 allocations with this patch, on debug and ASan.

@bukka
bukka force-pushed the stream_filter_user_unconsumed_buckets branch from 95f0821 to 2840ab1 Compare November 6, 2026 21:43
The callers expect the input brigade to be empty when the filter returns,
so buckets left on it leaked. Buckets put back with PSFS_FEED_ME to be seen
again with the next data are now kept by the user filter and prepended to
its input on the next call, which also fixes them aliasing the read chunk
buffer, being re-filtered by preceding filters in a chain and being lost
on the write path. Leftover buckets on any other status, or on the closing
call, are released with the existing warning.

Closes phpGH-20058

Co-authored-by: Nora Dossche <[email protected]>
Co-authored-by: Matthias Goergens <[email protected]>
@bukka
bukka force-pushed the stream_filter_user_unconsumed_buckets branch from 2840ab1 to 9714798 Compare November 6, 2026 21:44
@bukka

bukka commented Nov 6, 2026

Copy link
Copy Markdown
Member Author

Two things I noticed while testing this on PHP-8.4 with tests from master: ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt and stream_filter_register_class_coerce_consumed_by_ref_param.phpt (master only, --XFAIL-- This leaks memory) pass with this patch, so their XFAIL sections should be dropped when merging up. And the reentrant case from #23440 (an error handler that appends a bucket to $in while handling the "Unprocessed filter buckets" warning) still leaks 2 allocations with this patch, on debug and ASan.

Good points. All should be fixed now.

@bukka bukka closed this in 662bc31 Nov 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants