From: Stefan Marr Date: Fri, 18 Nov 2011 13:49:07 +0000 (+0000) Subject: Fixes Bug #54441 (Handling of changing modifiers on a trait alias) X-Git-Tag: php-5.5.0alpha1~866 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e150100f36a8820eeb19f9212fa0df03142a5c18;p=php Fixes Bug #54441 (Handling of changing modifiers on a trait alias) # this now results also in a compilation error, since it would open the door for inconsistencies, and violates the DRY principle. --- diff --git a/Zend/tests/traits/bug54441.phpt b/Zend/tests/traits/bug54441.phpt new file mode 100644 index 0000000000..84139f326b --- /dev/null +++ b/Zend/tests/traits/bug54441.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #54441 (Changing trait static method visibility) +--FILE-- + +--EXPECTF-- +Fatal error: The modifiers for the trait alias dontKnow() need to be changed in the same statment in which the alias is defined. Error in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index da29cec913..b29c633889 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4320,16 +4320,49 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce TSRMLS_DC) /* {{{ */ { int i = 0; + zend_trait_alias* cur_alias; + char* lc_method_name; if (ce->trait_aliases) { while (ce->trait_aliases[i]) { + cur_alias = ce->trait_aliases[i]; /** The trait for this alias has not been resolved, this means, this alias was not applied. Abort with an error. */ - if (!ce->trait_aliases[i]->trait_method->ce) { - zend_error(E_COMPILE_ERROR, - "An alias (%s) was defined for method %s(), but this method does not exist", - ce->trait_aliases[i]->alias, - ce->trait_aliases[i]->trait_method->method_name); + if (!cur_alias->trait_method->ce) { + if (cur_alias->alias) { + /** Plain old inconsistency/typo/bug */ + zend_error(E_COMPILE_ERROR, + "An alias (%s) was defined for method %s(), but this method does not exist", + cur_alias->alias, + cur_alias->trait_method->method_name); + } + else { + /** Here are two possible cases: + 1) this is an attempt to modifiy the visibility + of a method introduce as part of another alias. + Since that seems to violate the DRY principle, + we check against it and abort. + 2) it is just a plain old inconsitency/typo/bug + as in the case where alias is set. */ + + lc_method_name = zend_str_tolower_dup(cur_alias->trait_method->method_name, + cur_alias->trait_method->mname_len); + if (zend_hash_exists(&ce->function_table, + lc_method_name, + cur_alias->trait_method->mname_len+1)) { + efree(lc_method_name); + zend_error(E_COMPILE_ERROR, + "The modifiers for the trait alias %s() need to be changed in the same statment in which the alias is defined. Error", + cur_alias->trait_method->method_name); + } + else { + efree(lc_method_name); + zend_error(E_COMPILE_ERROR, + "The modifiers of the trait method %s() are changed, but this method does not exist. Error", + cur_alias->trait_method->method_name); + + } + } } i++; }