Skip to content

Commit

Permalink
Fix delayed early bind if class already exists
Browse files Browse the repository at this point in the history
We should not try to perform a delayed early bind if the class has
already been declared. This matches the behavior of an ordinary
early bind.
  • Loading branch information
nikic committed Oct 14, 2021
1 parent 7193909 commit 89007f6
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
5 changes: 5 additions & 0 deletions Zend/tests/no_early_binding_if_already_declared.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php
if (class_exists(B::class)) {
return;
}
class B extends A {}
11 changes: 11 additions & 0 deletions Zend/tests/no_early_binding_if_already_declared.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--TEST--
No early binding should occur if the class is already declared
--FILE--
<?php
class A {}
class B extends A {}
include __DIR__ . '/no_early_binding_if_already_declared.inc';
?>
===DONE===
--EXPECT--
===DONE===
2 changes: 1 addition & 1 deletion ext/opcache/tests/bug67215.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ unlink($file_c);
unlink($file_p);
?>
--EXPECTF--
Fatal error: Cannot declare class c, because the name is already in use in %sbug67215.c.php on line %d
Fatal error: Cannot declare class p, because the name is already in use in %sbug67215.p.php on line %d
21 changes: 12 additions & 9 deletions ext/opcache/zend_accelerator_util_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,18 +320,21 @@ static void zend_accel_do_delayed_early_binding(
CG(in_compilation) = 1;
for (uint32_t i = 0; i < persistent_script->num_early_bindings; i++) {
zend_early_binding *early_binding = &persistent_script->early_bindings[i];
zval *zv = zend_hash_find_known_hash(EG(class_table), early_binding->rtd_key);
if (zv) {
zend_class_entry *ce = Z_CE_P(zv);
zend_class_entry *parent_ce =
zend_hash_find_ex_ptr(EG(class_table), early_binding->lc_parent_name, 1);
if (parent_ce) {
ce = zend_try_early_bind(ce, parent_ce, early_binding->lcname, zv);
if (ce && early_binding->cache_slot != (uint32_t) -1) {
*(void**)((char*)run_time_cache + early_binding->cache_slot) = ce;
zend_class_entry *ce = zend_hash_find_ex_ptr(EG(class_table), early_binding->lcname, 1);
if (!ce) {
zval *zv = zend_hash_find_known_hash(EG(class_table), early_binding->rtd_key);
if (zv) {
zend_class_entry *orig_ce = Z_CE_P(zv);
zend_class_entry *parent_ce =
zend_hash_find_ex_ptr(EG(class_table), early_binding->lc_parent_name, 1);
if (parent_ce) {
ce = zend_try_early_bind(orig_ce, parent_ce, early_binding->lcname, zv);
}
}
}
if (ce && early_binding->cache_slot != (uint32_t) -1) {
*(void**)((char*)run_time_cache + early_binding->cache_slot) = ce;
}
}
CG(compiled_filename) = orig_compiled_filename;
CG(in_compilation) = orig_in_compilation;
Expand Down

0 comments on commit 89007f6

Please sign in to comment.