[GIT-PULLS] [php-src] PR #22690: Fix keyed iterator value lifetime across reentrant key() calls
[email protected] (PuH4ck3rX)
| Newsgroups | php.git-pulls |
|---|---|
| Message-ID | <[email protected]> |
Pull Request: https://github.com/php/php-src/pull/22690 Author: PuH4ck3rX Keyed iterator consumers fetch the current value before fetching the key. Fetching the key may call user code, and a reentrant key() implementation can advance a RecursiveIteratorIterator far enough to destroy the child zend_user_iterator that owns the cached current-value zval. iterator_to_array() and keyed foreach then continue using the borrowed pointer. This change copies the current zval before invoking get_current_key() in both consumers: - spl_iterator_to_array_apply() uses the retained value for insertion and releases it on success or exception. - zend_fe_fetch_object_helper retains the value across key lookup and releases it after CV or temporary-result assignment. The generated VM executor is updated accordingly. The regression test deterministically replaces the destroyed child iterator with a same-layout IteratorIterator. Before the fix, iterator_to_array() and both foreach assignment forms consume the replacement value; after the fix, they preserve the value fetched before key() reentry. Checks performed: - Built PHP 8.4 with ASan and UBSan, with opcache JIT disabled. - The new regression test passed. - 7 reduced reproducer scripts completed without sanitizer findings. - 47 targeted foreach and iterator tests passed. - The complete SPL test suite passed on the native WSL filesystem: 764 passed, 10 skipped, 1 expected failure, 0 failed.