From: Stefan Marr Date: Tue, 1 Nov 2011 15:25:24 +0000 (+0000) Subject: Fixed Bug #60153 (Interface method prototypes not enforced when implementd via traits.) X-Git-Tag: php-5.4.0RC1~47 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4591498df78e5f80b6ae70f04bb39812de82c2b4;p=php Fixed Bug #60153 (Interface method prototypes not enforced when implementd via traits.) # Moved the freeing of overriden functions to a point after the check. # The new check comes after the normal inheritance check to give the first check # the opportunity to abort with a more detailed error. # Also fixed a small type in an unrelated test. --- diff --git a/Zend/tests/traits/bug60153.phpt b/Zend/tests/traits/bug60153.phpt new file mode 100644 index 0000000000..8f01e72c2d --- /dev/null +++ b/Zend/tests/traits/bug60153.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #60153 (Interface method prototypes not enforced when implementd via traits.) +--FILE-- +common.scope != ce) { add = 1; /* or inherited from other class or interface */ - /* it is just a reference which was added to the subclass while doing the inheritance */ - /* so we can deleted now, and will add the overriding method afterwards */ - - /* except, if we try to add an abstract function, then we should not delete the inherited one */ - /* delete inherited fn if the function to be added is not abstract */ - if ((fn->common.fn_flags & ZEND_ACC_ABSTRACT) == 0) { - zend_hash_quick_del(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h); - } } if (add) { @@ -3871,6 +3863,23 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int if (prototype) { do_inheritance_check_on_method(fn, prototype TSRMLS_CC); } + /* one more thing: make sure we properly implement an abstract method */ + if (existing_fn && existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { + do_inheritance_check_on_method(fn, existing_fn TSRMLS_CC); + } + + /* delete inherited fn if the function to be added is not abstract */ + if (existing_fn + && existing_fn->common.scope != ce + && (fn->common.fn_flags & ZEND_ACC_ABSTRACT) == 0) { + /* it is just a reference which was added to the subclass while doing + the inheritance, so we can deleted now, and will add the overriding + method afterwards. + Except, if we try to add an abstract function, then we should not + delete the inherited one */ + zend_hash_quick_del(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h); + } + if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;