summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2013-03-21 21:10:32 +0800
committerXinchen Hui <laruence@php.net>2013-03-21 21:10:32 +0800
commit79925094c40a46a270fc079ddd6c2c92ff62c10f (patch)
tree06c69df2c9ef320294ae384500bf4159f2d518f9 /Zend
parentf2383dead69d59143fee1d54de98f154d6833714 (diff)
parent7dce0194c815cdc75a780b6471660042aed7bd7a (diff)
downloadphp-git-79925094c40a46a270fc079ddd6c2c92ff62c10f.tar.gz
Merge branch 'PHP-5.4' into PHP-5.5
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/bug64239_1.phpt26
-rw-r--r--Zend/tests/bug64239_2.phpt58
-rw-r--r--Zend/tests/bug64239_3.phpt33
-rw-r--r--Zend/tests/bug64239_4.phpt31
-rw-r--r--Zend/zend_API.c56
-rw-r--r--Zend/zend_API.h3
-rw-r--r--Zend/zend_builtin_functions.c20
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);