Skip to content

Commit 771bfaf

Browse files
committed
Remove dynamic defs from property hooks
Otherwise this hits an assertion failure in pass2 reversal and causes a subsequent crash. Closes GH-19206.
1 parent 9ce51da commit 771bfaf

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ PHP NEWS
4747
. Reset global pointers to prevent use-after-free in zend_jit_status().
4848
(Florian Engelhardt)
4949
. Fix issue with JIT restart and hooks. (nielsdos)
50+
. Fix crash with dynamic function defs in hooks during preload. (nielsdos)
5051

5152
- OpenSSL:
5253
. Fixed bug GH-18986 (OpenSSL backend: incorrect RAND_{load,write}_file()

ext/opcache/ZendAccelerator.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4132,6 +4132,24 @@ static void preload_link(void)
41324132
preload_remove_declares(op_array);
41334133
}
41344134
} ZEND_HASH_FOREACH_END();
4135+
4136+
if (ce->num_hooked_props > 0) {
4137+
zend_property_info *info;
4138+
4139+
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, info) {
4140+
if (info->hooks) {
4141+
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
4142+
if (info->hooks[i]) {
4143+
op_array = &info->hooks[i]->op_array;
4144+
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
4145+
if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
4146+
preload_remove_declares(op_array);
4147+
}
4148+
}
4149+
}
4150+
}
4151+
} ZEND_HASH_FOREACH_END();
4152+
}
41354153
} ZEND_HASH_FOREACH_END();
41364154
}
41374155

ext/opcache/tests/preload_dynamic_def_removal.inc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ class Test {
55
echo "dynamic\n";
66
}
77
}
8+
9+
public int $hook {
10+
get {
11+
function dynamic_in_hook() {
12+
echo "dynamic in hook\n";
13+
}
14+
return 1;
15+
}
16+
}
817
}
918

1019
function func() {
@@ -16,3 +25,4 @@ function func() {
1625
$test = new Test;
1726
$test->method();
1827
func();
28+
$test->hook;

ext/opcache/tests/preload_dynamic_def_removal.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows
1515
<?php
1616
dynamic();
1717
dynamic2();
18+
dynamic_in_hook();
1819
?>
1920
--EXPECT--
2021
dynamic
2122
dynamic2
23+
dynamic in hook

0 commit comments

Comments
 (0)