Skip to content

Commit 89007f6

Browse files
committed
Fix delayed early bind if class already exists
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.
1 parent 7193909 commit 89007f6

File tree

4 files changed

+29
-10
lines changed

4 files changed

+29
-10
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
if (class_exists(B::class)) {
3+
return;
4+
}
5+
class B extends A {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
No early binding should occur if the class is already declared
3+
--FILE--
4+
<?php
5+
class A {}
6+
class B extends A {}
7+
include __DIR__ . '/no_early_binding_if_already_declared.inc';
8+
?>
9+
===DONE===
10+
--EXPECT--
11+
===DONE===

ext/opcache/tests/bug67215.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ unlink($file_c);
2525
unlink($file_p);
2626
?>
2727
--EXPECTF--
28-
Fatal error: Cannot declare class c, because the name is already in use in %sbug67215.c.php on line %d
28+
Fatal error: Cannot declare class p, because the name is already in use in %sbug67215.p.php on line %d

ext/opcache/zend_accelerator_util_funcs.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -320,18 +320,21 @@ static void zend_accel_do_delayed_early_binding(
320320
CG(in_compilation) = 1;
321321
for (uint32_t i = 0; i < persistent_script->num_early_bindings; i++) {
322322
zend_early_binding *early_binding = &persistent_script->early_bindings[i];
323-
zval *zv = zend_hash_find_known_hash(EG(class_table), early_binding->rtd_key);
324-
if (zv) {
325-
zend_class_entry *ce = Z_CE_P(zv);
326-
zend_class_entry *parent_ce =
327-
zend_hash_find_ex_ptr(EG(class_table), early_binding->lc_parent_name, 1);
328-
if (parent_ce) {
329-
ce = zend_try_early_bind(ce, parent_ce, early_binding->lcname, zv);
330-
if (ce && early_binding->cache_slot != (uint32_t) -1) {
331-
*(void**)((char*)run_time_cache + early_binding->cache_slot) = ce;
323+
zend_class_entry *ce = zend_hash_find_ex_ptr(EG(class_table), early_binding->lcname, 1);
324+
if (!ce) {
325+
zval *zv = zend_hash_find_known_hash(EG(class_table), early_binding->rtd_key);
326+
if (zv) {
327+
zend_class_entry *orig_ce = Z_CE_P(zv);
328+
zend_class_entry *parent_ce =
329+
zend_hash_find_ex_ptr(EG(class_table), early_binding->lc_parent_name, 1);
330+
if (parent_ce) {
331+
ce = zend_try_early_bind(orig_ce, parent_ce, early_binding->lcname, zv);
332332
}
333333
}
334334
}
335+
if (ce && early_binding->cache_slot != (uint32_t) -1) {
336+
*(void**)((char*)run_time_cache + early_binding->cache_slot) = ce;
337+
}
335338
}
336339
CG(compiled_filename) = orig_compiled_filename;
337340
CG(in_compilation) = orig_in_compilation;

0 commit comments

Comments
 (0)