Repository navigation
Conversation
…es the options php_filter_call() kept a pointer to the options zval inside the caller's array. When the value is an object, converting it to a string runs __toString(), which can replace the options through a reference, so the filter then read a freed array. Keep a counted copy of the options for the duration of the call.
|
Quoted below: written with Claude, an LLM, as CONTRIBUTING.md asks us to mark. The builds and test runs behind it are on my machine; the commands to repeat them are under the fold.
|
|
Thanks for testing it. Agreed on pinning it, added the second case in 491341b: |
Fixes #24579
php_filter_call()keptoptionspointing at the zval inside the filter args (through the reference in the repro). For an object value,php_zval_filter()converts it to a string first, which runs__toString(); reassigning the referenced options there frees the array, and the filter then reads it (FETCH_LONG_OPTIONon what is now a string). The call now holds its own counted copy of the options zval and releases it on every exit, so the filter sees the options as they were when it was called.Added
ext/filter/tests/gh24579.phptwith the repro from the issue: it fails on PHP-8.4 (debug build aborts with the inconsistent hash table assertion) and passes with this. Allext/filter/testspass on a debug build.