From 0061db5503497458a85c40fb6bf1e2da80e7a036 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 16 Dec 2018 13:30:11 +0100 Subject: Fix #77291: magic methods inherited from a trait may be ignored MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adding methods from a trait, we must not assume that a method name with the same length as the name of the using class is either a PHP 4 style constructor, or not a magic method at all – it may well be another magic method. We mostly preserve the spirit of the optimization which caused this regression, and avoid string comparisons for all method names which can never be magic methods. --- Zend/zend_inheritance.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'Zend/zend_inheritance.c') diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 3a1497da7b..f3b62ef7e5 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1126,18 +1126,7 @@ static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zend_function* fe) /* {{{ */ { - if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) { - zend_string *lowercase_name = zend_string_tolower(ce->name); - lowercase_name = zend_new_interned_string(lowercase_name); - if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) { - if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) { - zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name)); - } - ce->constructor = fe; - fe->common.fn_flags |= ZEND_ACC_CTOR; - } - zend_string_release_ex(lowercase_name, 0); - } else if (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_') { + if (ZSTR_LEN(ce->name) != ZSTR_LEN(mname) && (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_')) { /* pass */ } else if (zend_string_equals_literal(mname, ZEND_CLONE_FUNC_NAME)) { ce->clone = fe; @@ -1168,6 +1157,17 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen ce->__tostring = fe; } else if (zend_string_equals_literal(mname, ZEND_DEBUGINFO_FUNC_NAME)) { ce->__debugInfo = fe; + } else if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) { + zend_string *lowercase_name = zend_string_tolower(ce->name); + lowercase_name = zend_new_interned_string(lowercase_name); + if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) { + if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) { + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name)); + } + ce->constructor = fe; + fe->common.fn_flags |= ZEND_ACC_CTOR; + } + zend_string_release_ex(lowercase_name, 0); } } /* }}} */ -- cgit v1.2.1