From: Guilherme Blanco Date: Sat, 6 Dec 2014 04:42:52 +0000 (+0000) Subject: Check interface/trait extension for internal classes X-Git-Tag: PRE_PHP7_EREG_MYSQL_REMOVALS~158 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4498d34aeaadcbc2ab64b9c0f40f336bf363b2d6;p=php Check interface/trait extension for internal classes Removed possibility to have extensions to declare classes extending interfaces or traits. It was checked in user classes, not extensions or internal. --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c9b67021f0..d4e71aa114 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -982,12 +982,6 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array return NULL; } - if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val); - } else if (parent_ce->ce_flags & ZEND_ACC_TRAIT) { - zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val); - } - zend_do_inheritance(ce, parent_ce); ce->refcount++; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index dbd81d8e1d..10633d73a7 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -767,15 +767,27 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent zend_string *key; zval *zv; - if ((ce->ce_flags & ZEND_ACC_INTERFACE) - && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name->val, parent_ce->name->val); - } - if (parent_ce->ce_flags & ZEND_ACC_FINAL) { - zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name->val, parent_ce->name->val); + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + /* Interface can only inherit other interfaces */ + if (!(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) { + zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name->val, parent_ce->name->val); + } + } else { + /* Class declaration must not extend traits or interfaces */ + if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) { + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val); + } else if (parent_ce->ce_flags & ZEND_ACC_TRAIT) { + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val); + } + + /* Class must not extend a final class */ + if (parent_ce->ce_flags & ZEND_ACC_FINAL) { + zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name->val, parent_ce->name->val); + } } ce->parent = parent_ce; + /* Copy serialize/unserialize callbacks */ if (!ce->serialize) { ce->serialize = parent_ce->serialize;