I suspect this is only a partial fix for the issue, it's probably
possible to recurse through a more complex pathway as well.
Fixes oss-fuzz #28961.
--- /dev/null
+--TEST--
+Infinite recursion in unlinked_instanceof()
+--FILE--
+<?php
+interface I {}
+spl_autoload_register(function() {
+ class X {
+ function test(): I {}
+ }
+ class Y extends X {
+ function test(): C {}
+ }
+});
+class C extends Z implements C {}
+?>
+--EXPECTF--
+Fatal error: Declaration of Y::test(): C must be compatible with X::test(): I in %s on line %d
zend_class_entry *ce = zend_lookup_class_ex(
ce1->interface_names[i].name, ce1->interface_names[i].lc_name,
ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
- if (ce && unlinked_instanceof(ce, ce2)) {
+ /* Avoid recursing if class implements ifself. */
+ if (ce && ce != ce1 && unlinked_instanceof(ce, ce2)) {
return 1;
}
}