diff options
author | Xinchen Hui <laruence@php.net> | 2013-03-21 21:10:32 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@php.net> | 2013-03-21 21:10:32 +0800 |
commit | 79925094c40a46a270fc079ddd6c2c92ff62c10f (patch) | |
tree | 06c69df2c9ef320294ae384500bf4159f2d518f9 /Zend | |
parent | f2383dead69d59143fee1d54de98f154d6833714 (diff) | |
parent | 7dce0194c815cdc75a780b6471660042aed7bd7a (diff) | |
download | php-git-79925094c40a46a270fc079ddd6c2c92ff62c10f.tar.gz |
Merge branch 'PHP-5.4' into PHP-5.5
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/bug64239_1.phpt | 26 | ||||
-rw-r--r-- | Zend/tests/bug64239_2.phpt | 58 | ||||
-rw-r--r-- | Zend/tests/bug64239_3.phpt | 33 | ||||
-rw-r--r-- | Zend/tests/bug64239_4.phpt | 31 | ||||
-rw-r--r-- | Zend/zend_API.c | 56 | ||||
-rw-r--r-- | Zend/zend_API.h | 3 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 20 |
7 files changed, 214 insertions, 13 deletions
diff --git a/Zend/tests/bug64239_1.phpt b/Zend/tests/bug64239_1.phpt index fe58cbd767..10d44c1817 100644 --- a/Zend/tests/bug64239_1.phpt +++ b/Zend/tests/bug64239_1.phpt @@ -3,20 +3,26 @@ Bug #64239 (get_class_methods() changed behavior) --FILE-- <?php class A { - public function test() { $this->backtrace(); } -} -class B { use T2 { t2method as Bmethod; } } + +class B extends A { +} + trait T2 { public function t2method() { } } -var_dump(get_class_methods("B")); +print_r(get_class_methods("A")); +print_r(get_class_methods("B")); --EXPECT-- -array(2) { - [0]=> - string(7) "bmethod" - [1]=> - string(8) "t2method" -} +Array +( + [0] => Bmethod + [1] => t2method +) +Array +( + [0] => Bmethod + [1] => t2method +) diff --git a/Zend/tests/bug64239_2.phpt b/Zend/tests/bug64239_2.phpt new file mode 100644 index 0000000000..26cf8ee1af --- /dev/null +++ b/Zend/tests/bug64239_2.phpt @@ -0,0 +1,58 @@ +--TEST-- +Bug #64239 (debug_backtrace() changed behavior) +--FILE-- +<?php +class A { + use T1; + public function test() { $this->backtrace(); } +} + +class B { + use T2 { t2method as Bmethod; } +} + +class C extends A { +} + +trait T1 { + protected function backtrace() { + $b = new B(); + $b->Bmethod(); + } +} +trait T2 { + public function t2method() { + print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)); + } +} +$a = new A(); +$a->test(); + +$c = new C(); +$c->test(); +?> +--EXPECTF-- +Array +( + [0] => Array + ( + [file] => %sbug64239_2.php + [line] => %d + [function] => Bmethod + [class] => B + [type] => -> + ) + +) +Array +( + [0] => Array + ( + [file] => %sbug64239_2.php + [line] => %d + [function] => Bmethod + [class] => B + [type] => -> + ) + +) diff --git a/Zend/tests/bug64239_3.phpt b/Zend/tests/bug64239_3.phpt new file mode 100644 index 0000000000..15faeb9852 --- /dev/null +++ b/Zend/tests/bug64239_3.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #64239 (debug_print_backtrace() changed behavior) +--FILE-- +<?php +class A { + use T2 { t2method as Bmethod; } +} + +class C extends A { + public function Bmethod() { + debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); + } +} + +trait T2 { + public function t2method() { + debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); + } +} + +$a = new A(); +$a->Bmethod(); +$a->t2method(); + +$c = new C(); +$c->Bmethod(); +$c->t2method(); +?> +--EXPECTF-- +#0 A->Bmethod() called at [%sbug64239_3.php:%d] +#0 A->t2method() called at [%sbug64239_3.php:%d] +#0 C->Bmethod() called at [%sbug64239_3.php:%d] +#0 A->t2method() called at [%sbug64239_3.php:%d] diff --git a/Zend/tests/bug64239_4.phpt b/Zend/tests/bug64239_4.phpt new file mode 100644 index 0000000000..7ab761ef72 --- /dev/null +++ b/Zend/tests/bug64239_4.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #64239 (debug_print_backtrace() changed behavior) +--FILE-- +<?php +class A { + use T2 { t2method as Bmethod; } +} + +class C extends A { + public static function Bmethod() { + debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); + } +} + +trait T2 { + public static function t2method() { + debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); + } +} + +A::Bmethod(); +A::t2method(); + +C::Bmethod(); +C::t2method(); +?> +--EXPECTF-- +#0 A::Bmethod() called at [%sbug64239_4.php:%d] +#0 A::t2method() called at [%sbug64239_4.php:%d] +#0 C::Bmethod() called at [%sbug64239_4.php:%d] +#0 A::t2method() called at [%sbug64239_4.php:%d] diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 1f400dea13..e867ca5dac 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3976,6 +3976,62 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC) } /* }}} */ +ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name, zend_uint len) /* {{{ */ +{ + zend_trait_alias *alias, **alias_ptr; + + alias_ptr = ce->trait_aliases; + alias = *alias_ptr; + while (alias) { + if (alias->alias_len == len && + !strncasecmp(name, alias->alias, alias->alias_len)) { + return alias->alias; + } + alias_ptr++; + alias = *alias_ptr; + } + + return name; +} +/* }}} */ + +ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_function *f) /* {{{ */ +{ + zend_function *func; + HashPosition iterator; + HashTable *function_table; + + if (f->common.type != ZEND_USER_FUNCTION || + *(f->op_array.refcount) < 2 || + !f->common.scope || + !f->common.scope->trait_aliases) { + return f->common.function_name; + } + + function_table = &ce->function_table; + zend_hash_internal_pointer_reset_ex(function_table, &iterator); + while (zend_hash_get_current_data_ex(function_table, (void **)&func, &iterator) == SUCCESS) { + if (func == f) { + char *name; + uint len; + ulong idx; + + if (zend_hash_get_current_key_ex(function_table, &name, &len, &idx, 0, &iterator) != HASH_KEY_IS_STRING) { + return f->common.function_name; + } + --len; + if (len == strlen(f->common.function_name) && + !strncasecmp(name, f->common.function_name, len)) { + return f->common.function_name; + } + return zend_find_alias_name(f->common.scope, name, len); + } + zend_hash_move_forward_ex(function_table, &iterator); + } + return f->common.function_name; +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_API.h b/Zend/zend_API.h index c26141b183..26aa1e6b17 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -521,6 +521,9 @@ ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC); ZEND_API void zend_rebuild_symbol_table(TSRMLS_D); +ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name, zend_uint len); +ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_function *f); + #define add_method(arg, key, method) add_assoc_function((arg), (key), (method)) ZEND_API ZEND_FUNCTION(display_disabled_function); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index ee75f521fe..d61aba14bd 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1092,7 +1092,7 @@ ZEND_FUNCTION(get_class_methods) (len != key_len - 1 || !same_name(key, mptr->common.function_name, len))) { MAKE_STD_ZVAL(method_name); - ZVAL_STRINGL(method_name, key, key_len - 1, 1); + ZVAL_STRINGL(method_name, zend_find_alias_name(mptr->common.scope, key, key_len - 1), key_len - 1, 1); zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL); } else { MAKE_STD_ZVAL(method_name); @@ -2103,7 +2103,14 @@ ZEND_FUNCTION(debug_print_backtrace) lineno = 0; } - function_name = ptr->function_state.function->common.function_name; + function_name = (ptr->function_state.function->common.scope && + ptr->function_state.function->common.scope->trait_aliases) ? + zend_resolve_method_name( + ptr->object ? + Z_OBJCE_P(ptr->object) : + ptr->function_state.function->common.scope, + ptr->function_state.function) : + ptr->function_state.function->common.function_name; if (function_name) { if (ptr->object) { @@ -2284,7 +2291,14 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int filename = NULL; } - function_name = ptr->function_state.function->common.function_name; + function_name = (ptr->function_state.function->common.scope && + ptr->function_state.function->common.scope->trait_aliases) ? + zend_resolve_method_name( + ptr->object ? + Z_OBJCE_P(ptr->object) : + ptr->function_state.function->common.scope, + ptr->function_state.function) : + ptr->function_state.function->common.function_name; if (function_name) { add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1); |