Skip to content

Commit b722b08

Browse files
committed
fix: opcache static cache hooks
1 parent ee8f619 commit b722b08

5 files changed

Lines changed: 72 additions & 8 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
OPcache static cache init hooks are request guarded
3+
--SKIPIF--
4+
<?php
5+
$zendDir = dirname(__DIR__);
6+
foreach (['zend_object_handlers.c', 'zend_vm_def.h', 'zend_vm_execute.h'] as $file) {
7+
if (!is_file($zendDir . '/' . $file)) {
8+
die('skip source tree required');
9+
}
10+
}
11+
?>
12+
--FILE--
13+
<?php
14+
15+
function requireGuardedHook(string $source, string $file, string $hook, int $minimum): void
16+
{
17+
$unguarded = 'UNEXPECTED(' . $hook . ' != NULL)';
18+
if (str_contains($source, $unguarded)) {
19+
throw new RuntimeException($file . ' calls ' . $hook . ' without the request guard');
20+
}
21+
22+
$pattern = '/EG\\(static_cache_class_access_active\\) &&\\s+' . preg_quote($hook, '/') . ' != NULL\\)\\s*\\)?\\s*\\{\\s+' . preg_quote($hook, '/') . '\\(/s';
23+
if (preg_match_all($pattern, $source) < $minimum) {
24+
throw new RuntimeException($file . ' is missing the guarded ' . $hook . ' calls');
25+
}
26+
}
27+
28+
$zendDir = dirname(__DIR__);
29+
30+
requireGuardedHook(
31+
file_get_contents($zendDir . '/zend_object_handlers.c'),
32+
'zend_object_handlers.c',
33+
'zend_class_init_statics_hook',
34+
1
35+
);
36+
37+
foreach (['zend_vm_def.h' => 2, 'zend_vm_execute.h' => 4] as $file => $minimum) {
38+
requireGuardedHook(
39+
file_get_contents($zendDir . '/' . $file),
40+
$file,
41+
'zend_function_init_statics_hook',
42+
$minimum
43+
);
44+
}
45+
46+
echo "OK\n";
47+
48+
?>
49+
--EXPECT--
50+
OK

Zend/zend_globals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ struct _zend_executor_globals {
269269

270270
bool active;
271271

272-
bool static_cache_class_access_active; /* fast guard for zend_class_static_access_hook */
272+
bool static_cache_class_access_active; /* fast guard for OPcache static cache hooks */
273273
bool tracked_mutation_hooks_active; /* fast guard for tracked array/object mutation hooks */
274274

275275
uint8_t flags;

Zend/zend_object_handlers.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,9 @@ ZEND_API void zend_class_init_statics(zend_class_entry *class_type) /* {{{ */
20952095
}
20962096
}
20972097

2098-
if (UNEXPECTED(zend_class_init_statics_hook != NULL)) {
2098+
if (UNEXPECTED(EG(static_cache_class_access_active) &&
2099+
zend_class_init_statics_hook != NULL)
2100+
) {
20992101
zend_class_init_statics_hook(class_type);
21002102
}
21012103
}

Zend/zend_vm_def.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9267,7 +9267,9 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, ANY, REF)
92679267

92689268
SAVE_OPLINE();
92699269

9270-
if (UNEXPECTED(zend_function_init_statics_hook != NULL)) {
9270+
if (UNEXPECTED(EG(static_cache_class_access_active) &&
9271+
zend_function_init_statics_hook != NULL)
9272+
) {
92719273
zend_function_init_statics_hook(execute_data);
92729274
}
92739275

@@ -9322,7 +9324,9 @@ ZEND_VM_HANDLER(203, ZEND_BIND_INIT_STATIC_OR_JMP, CV, JMP_ADDR)
93229324

93239325
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
93249326

9325-
if (UNEXPECTED(zend_function_init_statics_hook != NULL)) {
9327+
if (UNEXPECTED(EG(static_cache_class_access_active) &&
9328+
zend_function_init_statics_hook != NULL)
9329+
) {
93269330
zend_function_init_statics_hook(execute_data);
93279331
}
93289332

Zend/zend_vm_execute.h

Lines changed: 12 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)