Commit 9c034f3
committed
Fix early binding blocked by internal interfaces (Stringable, Countable, etc.)
When a class implements an internal interface, either implicitly
(Stringable via __toString()) or explicitly (Countable, ArrayAccess,
IteratorAggregate, etc.), the early binding guard in
zend_compile_class_decl() rejects it because ce->num_interfaces is
non-zero. This prevents hoisting, causing "Class not found" fatal
errors on forward references like:
class B extends A {}
class A { public function __toString(): string { return ''; } }
Since certain internal interfaces are registered during engine startup
and are always available, they should not prevent early binding.
An allowlist of known-safe core interfaces is used rather than allowing
all internal interfaces, because some have interface_gets_implemented
callbacks that can trigger fatal errors or user-observable side effects
at compile time (e.g. DateTimeInterface, Throwable, Serializable).
Changes:
- Add zend_can_early_bind_interfaces() using an allowlist of known-safe
internal interfaces (Stringable, Countable, ArrayAccess, Iterator,
IteratorAggregate, Traversable). Interfaces without a callback are
always safe; those with callbacks are only allowed if explicitly
listed.
- Add zend_early_bind_resolve_internal_interfaces() to resolve interface
names via zend_do_implement_interfaces() during early binding, with
correct handling of overlapping interface hierarchies.
- Extend zend_try_early_bind() to resolve a class's own interfaces when
early binding with a parent, and build the traits_and_interfaces array
for opcache's inheritance cache. Also support parent_ce=NULL for
no-parent classes during opcache's delayed early binding.
- Update opcache's zend_accel_do_delayed_early_binding() to also bind
no-parent classes with internal interfaces (empty lc_parent_name).
- Handle polyfill patterns in zend_bind_class_in_slot(): when a
non-toplevel runtime ZEND_DECLARE_CLASS collides with a toplevel
class that was early-bound at compile time, replace the early-bound
entry instead of erroring. This supports patterns like:
if (PHP_VERSION_ID >= 80000) {
class Foo extends \Bar {} // non-toplevel, executes
return;
}
class Foo { ... } // toplevel, early-bound
Detected via ZEND_ACC_TOP_LEVEL: old class has it, new class doesn't.
Closes GH-7873
Closes GH-8323
Closes GH-197291 parent 58acc67 commit 9c034f3
File tree
5 files changed
+334
-29
lines changed- Zend
- tests
- ext/opcache
5 files changed
+334
-29
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1335 | 1335 | | |
1336 | 1336 | | |
1337 | 1337 | | |
1338 | | - | |
1339 | | - | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
1340 | 1366 | | |
1341 | 1367 | | |
1342 | 1368 | | |
| |||
5140 | 5166 | | |
5141 | 5167 | | |
5142 | 5168 | | |
5143 | | - | |
| 5169 | + | |
5144 | 5170 | | |
5145 | 5171 | | |
5146 | 5172 | | |
| |||
9527 | 9553 | | |
9528 | 9554 | | |
9529 | 9555 | | |
| 9556 | + | |
| 9557 | + | |
| 9558 | + | |
| 9559 | + | |
| 9560 | + | |
| 9561 | + | |
| 9562 | + | |
| 9563 | + | |
| 9564 | + | |
| 9565 | + | |
| 9566 | + | |
| 9567 | + | |
| 9568 | + | |
| 9569 | + | |
| 9570 | + | |
| 9571 | + | |
| 9572 | + | |
| 9573 | + | |
| 9574 | + | |
| 9575 | + | |
| 9576 | + | |
| 9577 | + | |
| 9578 | + | |
| 9579 | + | |
| 9580 | + | |
| 9581 | + | |
| 9582 | + | |
| 9583 | + | |
| 9584 | + | |
| 9585 | + | |
| 9586 | + | |
| 9587 | + | |
| 9588 | + | |
| 9589 | + | |
| 9590 | + | |
| 9591 | + | |
| 9592 | + | |
| 9593 | + | |
| 9594 | + | |
| 9595 | + | |
| 9596 | + | |
| 9597 | + | |
| 9598 | + | |
| 9599 | + | |
9530 | 9600 | | |
9531 | 9601 | | |
9532 | 9602 | | |
| |||
9648 | 9718 | | |
9649 | 9719 | | |
9650 | 9720 | | |
9651 | | - | |
9652 | | - | |
| 9721 | + | |
| 9722 | + | |
| 9723 | + | |
| 9724 | + | |
| 9725 | + | |
| 9726 | + | |
| 9727 | + | |
| 9728 | + | |
| 9729 | + | |
| 9730 | + | |
| 9731 | + | |
| 9732 | + | |
| 9733 | + | |
| 9734 | + | |
9653 | 9735 | | |
9654 | | - | |
9655 | | - | |
| 9736 | + | |
9656 | 9737 | | |
9657 | 9738 | | |
9658 | 9739 | | |
| |||
9667 | 9748 | | |
9668 | 9749 | | |
9669 | 9750 | | |
9670 | | - | |
9671 | | - | |
9672 | | - | |
9673 | | - | |
9674 | | - | |
9675 | | - | |
9676 | | - | |
9677 | 9751 | | |
9678 | | - | |
| 9752 | + | |
| 9753 | + | |
| 9754 | + | |
| 9755 | + | |
| 9756 | + | |
| 9757 | + | |
| 9758 | + | |
| 9759 | + | |
| 9760 | + | |
| 9761 | + | |
| 9762 | + | |
| 9763 | + | |
| 9764 | + | |
| 9765 | + | |
| 9766 | + | |
9679 | 9767 | | |
9680 | 9768 | | |
9681 | 9769 | | |
9682 | 9770 | | |
9683 | 9771 | | |
9684 | | - | |
9685 | 9772 | | |
| 9773 | + | |
| 9774 | + | |
| 9775 | + | |
| 9776 | + | |
9686 | 9777 | | |
9687 | 9778 | | |
9688 | 9779 | | |
| |||
9727 | 9818 | | |
9728 | 9819 | | |
9729 | 9820 | | |
9730 | | - | |
9731 | | - | |
| 9821 | + | |
| 9822 | + | |
| 9823 | + | |
9732 | 9824 | | |
9733 | 9825 | | |
9734 | 9826 | | |
| |||
0 commit comments