From: Antony Dovgal Date: Mon, 17 Mar 2008 14:53:43 +0000 (+0000) Subject: fix #39127i (Old-style constructor fallbacks produce strange results) X-Git-Tag: RELEASE_2_0_0a1~122 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=abbd1e8ecef08c2eda7fd0da073db21cdde992dd;p=php fix #39127i (Old-style constructor fallbacks produce strange results) --- diff --git a/Zend/tests/bug39127.phpt b/Zend/tests/bug39127.phpt new file mode 100644 index 0000000000..c05bcd3f73 --- /dev/null +++ b/Zend/tests/bug39127.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #39127 (Old-style constructor fallbacks produce strange results) +--FILE-- + +--EXPECTF-- +%s(13) "a::a() called" +bool(true) +bool(false) +bool(false) +Done diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b19194b62a..ffaf67a73a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2417,12 +2417,19 @@ static void do_inherit_parent_constructor(zend_class_entry *ce TSRMLS_DC) /* {{{ } else if (ce->parent->constructor) { ce->constructor = ce->parent->constructor; if (!zend_ascii_hash_exists(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) { - unsigned int lc_class_name_len; - zstr lc_class_name = zend_u_str_case_fold(ZEND_STR_TYPE, ce->name, ce->name_length, 0, &lc_class_name_len); - - zend_u_hash_update(&ce->function_table, ZEND_STR_TYPE, lc_class_name, lc_class_name_len+1, ce->constructor, sizeof(zend_function), NULL); - function_add_ref(ce->constructor TSRMLS_CC); - efree(lc_class_name.v); + unsigned int lc_parent_class_name_len; + zend_function *function; + zstr lc_parent_class_name = zend_u_str_case_fold(ZEND_STR_TYPE, ce->parent->name, ce->parent->name_length, 0, &lc_parent_class_name_len); + + if (!zend_u_hash_exists(&ce->function_table, ZEND_STR_TYPE, lc_parent_class_name, ce->parent->name_length+1) && + zend_u_hash_find(&ce->parent->function_table, ZEND_STR_TYPE, lc_parent_class_name, ce->parent->name_length+1, (void **)&function)==SUCCESS) { + if (function->common.fn_flags & ZEND_ACC_CTOR) { + /* inherit parent's constructor */ + zend_u_hash_update(&ce->function_table, ZEND_STR_TYPE, lc_parent_class_name, ce->parent->name_length+1, function, sizeof(zend_function), NULL); + function_add_ref(function); + } + } + efree(lc_parent_class_name.v); } } } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 09ec4a7fea..04f0a62ea6 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -905,9 +905,22 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_uchar type, zstr function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */ { - zend_function *fbc; + zend_function *fbc = NULL; + + if (function_name_strlen == ce->name_length && ce->constructor) { + zstr lc_class_name; + unsigned int lc_class_name_len, real_len; + + lc_class_name = zend_u_str_case_fold(type, ce->name, ce->name_length, 0, &lc_class_name_len); + real_len = USTR_BYTES(type, lc_class_name_len); + + if (!memcmp(lc_class_name.s, function_name_strval.s, real_len)) { + fbc = ce->constructor; + } + efree(lc_class_name.v); + } - if (zend_u_hash_find(&ce->function_table, type, function_name_strval, function_name_strlen + 1, (void **) &fbc)==FAILURE) { + if (!fbc && zend_u_hash_find(&ce->function_table, type, function_name_strval, function_name_strlen + 1, (void **) &fbc)==FAILURE) { if (ce->__call && EG(This) && Z_OBJ_HT_P(EG(This))->get_class_entry &&