Remove dynamic defs from property hooks

Otherwise this hits an assertion failure in pass2 reversal and causes a
subsequent crash.

Closes GH-19206.
This commit is contained in:
Niels Dossche 2025-07-21 22:44:03 +02:00
parent 9ce51dad8b
commit 771bfaf34d
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
4 changed files with 31 additions and 0 deletions

1
NEWS
View file

@ -47,6 +47,7 @@ PHP NEWS
. Reset global pointers to prevent use-after-free in zend_jit_status().
(Florian Engelhardt)
. Fix issue with JIT restart and hooks. (nielsdos)
. Fix crash with dynamic function defs in hooks during preload. (nielsdos)
- OpenSSL:
. Fixed bug GH-18986 (OpenSSL backend: incorrect RAND_{load,write}_file()

View file

@ -4132,6 +4132,24 @@ static void preload_link(void)
preload_remove_declares(op_array);
}
} ZEND_HASH_FOREACH_END();
if (ce->num_hooked_props > 0) {
zend_property_info *info;
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, info) {
if (info->hooks) {
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
if (info->hooks[i]) {
op_array = &info->hooks[i]->op_array;
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
preload_remove_declares(op_array);
}
}
}
}
} ZEND_HASH_FOREACH_END();
}
} ZEND_HASH_FOREACH_END();
}

View file

@ -5,6 +5,15 @@ class Test {
echo "dynamic\n";
}
}
public int $hook {
get {
function dynamic_in_hook() {
echo "dynamic in hook\n";
}
return 1;
}
}
}
function func() {
@ -16,3 +25,4 @@ function func() {
$test = new Test;
$test->method();
func();
$test->hook;

View file

@ -15,7 +15,9 @@ if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows
<?php
dynamic();
dynamic2();
dynamic_in_hook();
?>
--EXPECT--
dynamic
dynamic2
dynamic in hook