Skip to content

Commit 0dfb10d

Browse files
committed
Fix opcache checksum calc for inheritance_cache
Fixes phpGH-8065
1 parent 9bd9e9a commit 0dfb10d

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2114,7 +2114,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
21142114
unsigned int checksum = zend_accel_script_checksum(persistent_script);
21152115
if (checksum != persistent_script->dynamic_members.checksum ) {
21162116
/* The checksum is wrong */
2117-
zend_accel_error(ACCEL_LOG_INFO, "Checksum failed for '%s': expected=0x%08x, found=0x%08x",
2117+
zend_accel_error(ACCEL_LOG_WARNING, "Checksum failed for '%s': expected=0x%08x, found=0x%08x",
21182118
ZSTR_VAL(persistent_script->script.filename), persistent_script->dynamic_members.checksum, checksum);
21192119
zend_shared_alloc_lock();
21202120
if (!persistent_script->corrupted) {

ext/opcache/tests/gh8065.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
class Bar extends Foo {}

ext/opcache/tests/gh8065.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug GH-8065: Opcache chdir() breaks persistent script checksum
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.consistency_checks=1
7+
opcache.log_verbosity_level=2
8+
opcache.protect_memory=1
9+
--EXTENSIONS--
10+
opcache
11+
--FILE--
12+
<?php
13+
14+
class Foo {}
15+
16+
require_once __DIR__ . '/gh8065.inc';
17+
18+
echo "Done\n";
19+
20+
?>
21+
--EXPECT--
22+
Done

ext/opcache/zend_accelerator_util_funcs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,31 @@ unsigned int zend_accel_script_checksum(zend_persistent_script *persistent_scrip
353353
mem += (unsigned char*)persistent_script - mem;
354354
}
355355

356+
// zend_class_entry.inheritance_cache is mutated, so we need to reset it before
357+
HashTable inheritance_cache_backup;
358+
zend_hash_init(&inheritance_cache_backup, zend_hash_num_elements(&persistent_script->script.class_table), NULL, NULL, 0);
359+
zend_class_entry *class;
360+
ZEND_HASH_FOREACH_PTR(&persistent_script->script.class_table, class) {
361+
if (!class->inheritance_cache) {
362+
continue;
363+
}
364+
zend_hash_add_ptr(&inheritance_cache_backup, class->name, class->inheritance_cache);
365+
class->inheritance_cache = NULL;
366+
} ZEND_HASH_FOREACH_END();
367+
356368
zend_adler32(checksum, mem, persistent_script_check_block_size);
357369
mem += sizeof(*persistent_script);
358370
size -= sizeof(*persistent_script);
359371

360372
if (size > 0) {
361373
checksum = zend_adler32(checksum, mem, size);
362374
}
375+
376+
// Restore the zend_class_entry.inheritance_cache
377+
ZEND_HASH_FOREACH_PTR(&persistent_script->script.class_table, class) {
378+
class->inheritance_cache = zend_hash_find_ptr(&inheritance_cache_backup, class->name);
379+
} ZEND_HASH_FOREACH_END();
380+
zend_hash_destroy(&inheritance_cache_backup);
381+
363382
return checksum;
364383
}

0 commit comments

Comments
 (0)