]> granicus.if.org Git - php/commitdiff
Check interface/trait extension for internal classes
authorGuilherme Blanco <guilhermeblanco@hotmail.com>
Sat, 6 Dec 2014 04:42:52 +0000 (04:42 +0000)
committerNikita Popov <nikic@php.net>
Fri, 13 Feb 2015 14:31:48 +0000 (15:31 +0100)
Removed possibility to have extensions to declare classes extending
interfaces or traits. It was checked in user classes, not extensions
or internal.

Zend/zend_compile.c
Zend/zend_inheritance.c

index c9b67021f05ecb748a11bf5749edd8b83a3fe884..d4e71aa11460c85df51f44113f85dbb7be4492c4 100644 (file)
@@ -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++;
index dbd81d8e1d110898fb7a93fceda2a4fb6d8c9009..10633d73a761867eee7f212bcff339f501c6e31d 100644 (file)
@@ -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;