[php-src] PR #24140: Fix GH-23898: Keep user_filter_map alive until streams are closed

From: Date: Mon, 05 Oct 2026 17:07:51 +0000
Subject: [php-src] PR #24140: Fix GH-23898: Keep user_filter_map alive until streams are closed
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39172@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24140 Author: bukka BG(user_filter_map) is destroyed in the user_filters RSHUTDOWN but the factories in FG(stream_filters) stay until php_shutdown_stream_hashes(). Streams are closed only later in zend_deactivate() and closing a filtered stream runs the user filter() callback, so anything it does with user filters sees the two tables out of sync. Appending an already registered filter finds the factory but no map (GH-22449), re-registering the same name orphans a recreated map (GH-22818) and registering a new name recreates the map with just that entry, so a following append of the old name hits ZEND_ASSERT(ce) or a NULL dereference in release build (GH-23898). Free the map in a post-deactivate hook of the basic module instead. It runs after zend_deactivate() has closed all streams so no PHP callback can run anymore, and before php_shutdown_stream_hashes() frees the factories, so the map and the factories now live and die together. The map holds only class entry pointers without destructor so freeing it after the executor shutdown is fine. The GH-22449, GH-22818 and GH-23898 tests use a filter that opens a new filtered stream from every filter() call, which recurses forever once the append at shutdown works (same as on explicit fclose()). I added a one-shot guard to them and they now expect the registration and append to succeed. This is an alternative to #23904 which returns early from stream_filter_register() during resource shutdown. That stops the reported script from asserting but it is just another plaster like the previous GH-22449 and GH-22818 fixes, which turned one specific callback shape from a crash to a warning while leaving the actual lifetime mismatch in place. That's why we keep getting variants of the same bug. PHP 8.4 and 8.5 crash on the same scripts but as this needs user filter callbacks at shutdown, it targets just 8.6. Fixes GH-23898 Closes #23904

« previous php.git-pulls (#39172) next »