diff options
author | Antony Dovgal <tony2001@php.net> | 2008-03-17 14:54:42 +0000 |
---|---|---|
committer | Antony Dovgal <tony2001@php.net> | 2008-03-17 14:54:42 +0000 |
commit | 7dd943ac5cd5da1ab80c57fd4c822cb33f7c6c0f (patch) | |
tree | 9ee7506de11c4690bd9008e50bed8d42b55d8b03 | |
parent | 964e0522a12b91051be334b47237983a7e7b61ad (diff) | |
download | php-git-7dd943ac5cd5da1ab80c57fd4c822cb33f7c6c0f.tar.gz |
MFH: fix #39127 (Old-style constructor fallbacks produce strange results)
-rw-r--r-- | Zend/tests/bug39127.phpt | 21 | ||||
-rw-r--r-- | Zend/zend_compile.c | 5 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 12 |
3 files changed, 34 insertions, 4 deletions
diff --git a/Zend/tests/bug39127.phpt b/Zend/tests/bug39127.phpt new file mode 100644 index 0000000000..a013da145e --- /dev/null +++ b/Zend/tests/bug39127.phpt @@ -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-- +string(13) "a::a() called" +bool(true) +bool(false) +bool(false) +Done diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2e2c0fae93..f6af8c84aa 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2197,10 +2197,11 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length); if (!zend_hash_exists(&ce->function_table, lc_class_name, ce->name_length+1)) { lc_parent_class_name = zend_str_tolower_dup(ce->parent->name, ce->parent->name_length); - if (zend_hash_find(&ce->parent->function_table, lc_parent_class_name, ce->parent->name_length+1, (void **)&function)==SUCCESS) { + if (!zend_hash_exists(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1) && + zend_hash_find(&ce->parent->function_table, 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_hash_update(&ce->function_table, lc_class_name, ce->name_length+1, function, sizeof(zend_function), NULL); + zend_hash_update(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1, function, sizeof(zend_function), NULL); function_add_ref(function); } } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 449c32408b..5ec5826d61 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -892,9 +892,17 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */ { - zend_function *fbc; + zend_function *fbc = NULL; + char *lc_class_name; - if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen + 1, (void **) &fbc)==FAILURE) { + if (function_name_strlen == ce->name_length && ce->constructor) { + lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length); + if (!memcmp(lc_class_name, function_name_strval, function_name_strlen)) { + fbc = ce->constructor; + } + efree(lc_class_name); + } + if (!fbc && zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1, (void **) &fbc)==FAILURE) { if (ce->__call && EG(This) && Z_OBJ_HT_P(EG(This))->get_class_entry && |