diff --git a/NEWS b/NEWS index aa2961a6ec3..84006fc58f2 100644 --- a/NEWS +++ b/NEWS @@ -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() diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 83dedb1e742..1e661314f20 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -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(); } diff --git a/ext/opcache/tests/preload_dynamic_def_removal.inc b/ext/opcache/tests/preload_dynamic_def_removal.inc index 27ec69120ea..2a6a44ef509 100644 --- a/ext/opcache/tests/preload_dynamic_def_removal.inc +++ b/ext/opcache/tests/preload_dynamic_def_removal.inc @@ -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; diff --git a/ext/opcache/tests/preload_dynamic_def_removal.phpt b/ext/opcache/tests/preload_dynamic_def_removal.phpt index d4f2bb070cc..acc26873e18 100644 --- a/ext/opcache/tests/preload_dynamic_def_removal.phpt +++ b/ext/opcache/tests/preload_dynamic_def_removal.phpt @@ -15,7 +15,9 @@ if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows --EXPECT-- dynamic dynamic2 +dynamic in hook