[php-src] PR #25374: Fix stale PFA cache entries after the declaring site is freed
| From: | jorgsowa | Date: | Tue, 10 Nov 2026 17:09:20 +0000 |
| Subject: | [php-src] PR #25374: Fix stale PFA cache entries after the declaring site is freed | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-40516@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/25374
Author: jorgsowa
The request PFA cache is keyed on the address of the declaring site
(
&opline->lineno or &ast->lineno). Without SHM caching, this
memory can be freed while the cache entry is still alive:
- eval()'d op_arrays are freed after execution
- class constant ASTs are freed after evaluation
A later PFA allocated at the same address then hits the stale entry and gets an op_array compiled
for a different argument shape. This leads to wrong bound arguments, or out-of-bounds writes in
zp_bind() when the bound var counts differ.
Fix:
- Runtime PFAs: the cached op_array retains the declaring op_array via
dynamic_func_defs, like it already does for called closures.
- Const expr PFAs with a non-interned name: key on the name, which is unique per declaration and
kept alive by the cached op_array's function_name. Interned names mean the AST is
in persistent memory, so the address key is kept.
Trade-off: PFAs in eval()'d code keep that op_array alive until the end of the request.