com php-src: Partial fix for bug #64239: Zend/tests/bug64 239_1.phpt Zend/zend_builtin_functions.c
| From: | Dmitry Stogov | Date: | Tue, 19 Mar 2013 11:45:48 +0000 |
| Subject: | com php-src: Partial fix for bug #64239: Zend/tests/bug64 239_1.phpt Zend/zend_builtin_functions.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-71616@lists.php.net to get a copy of this message | ||
Commit: 984561cfa81adfd893833bce506544349b04c803
Author: Dmitry Stogov <dmitry@zend.com> Tue, 19 Mar 2013 15:45:48 +0400
Parents: 84630a1109084507bc0c78301db831328229f1cb
Branches: PHP-5.4 PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=984561cfa81adfd893833bce506544349b04c803
Log:
Partial fix for bug #64239
Bugs:
https://bugs.php.net/64239
Changed paths:
A Zend/tests/bug64239_1.phpt
M Zend/zend_builtin_functions.c
Diff:
diff --git a/Zend/tests/bug64239_1.phpt b/Zend/tests/bug64239_1.phpt
new file mode 100644
index 0000000..fe58cbd
--- /dev/null
+++ b/Zend/tests/bug64239_1.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #64239 (get_class_methods() changed behavior)
+--FILE--
+<?php
+class A {
+ public function test() { $this->backtrace(); }
+}
+class B {
+ use T2 { t2method as Bmethod; }
+}
+trait T2 {
+ public function t2method() {
+ }
+}
+var_dump(get_class_methods("B"));
+--EXPECT--
+array(2) {
+ [0]=>
+ string(7) "bmethod"
+ [1]=>
+ string(8) "t2method"
+}
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 1e85785..dcb1818 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1025,6 +1025,13 @@ ZEND_FUNCTION(get_object_vars)
}
/* }}} */
+static int same_name(const char *key, const char *name, zend_uint name_len)
+{
+ char *lcname = zend_str_tolower_dup(name, name_len);
+ int ret = memcmp(lcname, key, name_len) == 0;
+ efree(lcname);
+ return ret;
+}
/* {{{ proto array get_class_methods(mixed class)
Returns an array of method names for class or class instance. */
@@ -1072,14 +1079,26 @@ ZEND_FUNCTION(get_class_methods)
uint len = strlen(mptr->common.function_name);
/* Do not display old-style inherited constructors */
- if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
- mptr->common.scope == ce ||
- zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len,
&num_index, 0, &pos) != HASH_KEY_IS_STRING ||
- zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
-
+ if (zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len,
&num_index, 0, &pos) != HASH_KEY_IS_STRING) {
MAKE_STD_ZVAL(method_name);
ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
+ } else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
+ mptr->common.scope == ce ||
+ zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
+
+ if (mptr->type == ZEND_USER_FUNCTION &&
+ *mptr->op_array.refcount > 1 &&
+ (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);
+ zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *),
NULL);
+ } else {
+ MAKE_STD_ZVAL(method_name);
+ ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
+ zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *),
NULL);
+ }
}
}
zend_hash_move_forward_ex(&ce->function_table, &pos);
@@ -1640,14 +1659,6 @@ ZEND_FUNCTION(restore_exception_handler)
}
/* }}} */
-static int same_name(const char *key, const char *name, zend_uint name_len)
-{
- char *lcname = zend_str_tolower_dup(name, name_len);
- int ret = memcmp(lcname, key, name_len) == 0;
- efree(lcname);
- return ret;
-}
-
static int copy_class_or_interface_name(zend_class_entry **pce TSRMLS_DC, int num_args, va_list
args, zend_hash_key *hash_key)
{
zval *array = va_arg(args, zval *);