mirror of
https://github.com/php/php-src.git
synced 2026-03-27 09:42:22 +01:00
fix #39127i (Old-style constructor fallbacks produce strange results)
This commit is contained in:
21
Zend/tests/bug39127.phpt
Normal file
21
Zend/tests/bug39127.phpt
Normal file
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #39127 (Old-style constructor fallbacks produce strange results)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class a { function a() { var_dump("a::a() called"); } }
|
||||
class b extends a {}
|
||||
|
||||
$b = new b;
|
||||
var_dump(is_callable(array($b,"a")));
|
||||
var_dump(is_callable(array($b,"b")));
|
||||
var_dump(is_callable(array($b,"__construct")));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
%s(13) "a::a() called"
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
Done
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 (zend_u_hash_find(&ce->function_table, type, function_name_strval, function_name_strlen + 1, (void **) &fbc)==FAILURE) {
|
||||
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 (!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 &&
|
||||
|
||||
Reference in New Issue
Block a user