From: Dmitry Stogov Date: Tue, 25 Jun 2019 14:43:46 +0000 (+0300) Subject: Fixed variance check for abstract constructor during erlay binding X-Git-Tag: php-7.4.0alpha3~184 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f09d41ffc04894acda1c27851287f007bbd5a030;p=php Fixed variance check for abstract constructor during erlay binding --- diff --git a/Zend/tests/type_declarations/variance/abstract_constructor.phpt b/Zend/tests/type_declarations/variance/abstract_constructor.phpt new file mode 100644 index 0000000000..f061517bcf --- /dev/null +++ b/Zend/tests/type_declarations/variance/abstract_constructor.phpt @@ -0,0 +1,18 @@ +--TEST-- +Variance check for abstract constructor +--FILE-- + +--EXPECTF-- +Fatal error: Could not check compatibility between C::__construct(Y $x) and A::__construct(X $x), because class Y is not available in %s on line %d diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index af893bc112..c57d061793 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2395,9 +2395,19 @@ zend_bool zend_can_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce) zval *zv; zend_string *unresolved_class; - if ((parent_flags & ZEND_ACC_PRIVATE) || - ((parent_flags & ZEND_ACC_CTOR) && !(parent_flags & ZEND_ACC_ABSTRACT))) { + if (parent_flags & ZEND_ACC_PRIVATE) { continue; + } else if (parent_flags & ZEND_ACC_CTOR) { + zend_function *proto = parent_func->common.prototype ? + parent_func->common.prototype : parent_func; + + /* ctors only have a prototype if is abstract (or comes from an interface) */ + /* and if that is the case, we want to check inheritance against it */ + if (proto->common.fn_flags & ZEND_ACC_ABSTRACT) { + parent_func = proto; + } else { + continue; + } } zv = zend_hash_find_ex(&ce->function_table, key, 1);