Skip to content

Free previous state when re-calling Reflection*::__construct() - #203

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/reflection-method-reconstruct-leak
Closed

Free previous state when re-calling Reflection*::__construct()#203
iliaal wants to merge 1 commit into
PHP-8.4from
fix/reflection-method-reconstruct-leak

Conversation

@iliaal

@iliaal iliaal commented Jul 31, 2026

Copy link
Copy Markdown
Owner

ReflectionMethod::__construct() overwrites intern->ptr without releasing the previous value. When the reflected method is Closure::__invoke() that value is a trampoline allocated by zend_get_closure_invoke_method(), so every re-construct leaks one. ReflectionClassConstant::__construct() has the same shape for the $name and $class property slots and leaks a string reference whenever the constant name is not interned. ReflectionFunction, ReflectionParameter and ReflectionProperty already release prior state on re-entry.

$r = new ReflectionMethod(function () {}, '__invoke');
for ($i = 0; $i < 10000; $i++) {
    $r->__construct(function () {}, '__invoke');
}
// 2.5 MB of growth on PHP-8.4, zero with the patch

ReflectionMethod::__construct() overwrote intern->ptr without releasing
the previous Closure::__invoke() trampoline, and
ReflectionClassConstant::__construct() overwrote the $name and $class
slots without dropping their previous references. ReflectionFunction,
ReflectionParameter and ReflectionProperty already release prior state
on re-entry.

Closes phpGH-22968
@iliaal
iliaal force-pushed the fix/reflection-method-reconstruct-leak branch from cd9d932 to e3a79ed Compare July 31, 2026 13:27
@iliaal

iliaal commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

Promoted upstream as php#22968.

@iliaal iliaal closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant