From dd335359e950e52dd5e679da05b5c1f4084e5869 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 5 Jan 2021 13:02:30 +0100 Subject: [PATCH] Fix infinite recursion in unlinked_instanceof 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. --- .../variance/infinite_recursion.phpt | 17 +++++++++++++++++ Zend/zend_inheritance.c | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/type_declarations/variance/infinite_recursion.phpt diff --git a/Zend/tests/type_declarations/variance/infinite_recursion.phpt b/Zend/tests/type_declarations/variance/infinite_recursion.phpt new file mode 100644 index 0000000000..6eab6ff7a5 --- /dev/null +++ b/Zend/tests/type_declarations/variance/infinite_recursion.phpt @@ -0,0 +1,17 @@ +--TEST-- +Infinite recursion in unlinked_instanceof() +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of Y::test(): C must be compatible with X::test(): I in %s on line %d diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 882738b758..4b161692af 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -311,7 +311,8 @@ static zend_bool unlinked_instanceof(zend_class_entry *ce1, zend_class_entry *ce 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; } } -- 2.40.0