summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2008-03-17 14:54:42 +0000
committerAntony Dovgal <tony2001@php.net>2008-03-17 14:54:42 +0000
commit7dd943ac5cd5da1ab80c57fd4c822cb33f7c6c0f (patch)
tree9ee7506de11c4690bd9008e50bed8d42b55d8b03
parent964e0522a12b91051be334b47237983a7e7b61ad (diff)
downloadphp-git-7dd943ac5cd5da1ab80c57fd4c822cb33f7c6c0f.tar.gz
MFH: fix #39127 (Old-style constructor fallbacks produce strange results)
-rw-r--r--Zend/tests/bug39127.phpt21
-rw-r--r--Zend/zend_compile.c5
-rw-r--r--Zend/zend_object_handlers.c12
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 &&