Merge branch 'PHP-5.4' into PHP-5.5

This commit is contained in:
Xinchen Hui 2013-03-21 21:10:32 +08:00
commit 79925094c4
7 changed files with 214 additions and 13 deletions

View file

@ -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
)

View file

@ -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] => ->
)
)

View file

@ -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]

View file

@ -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]

View file

@ -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

View file

@ -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);

View file

@ -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);