]> granicus.if.org Git - php/commitdiff
Partial fix for bug #64239
authorDmitry Stogov <dmitry@zend.com>
Tue, 19 Mar 2013 11:45:48 +0000 (15:45 +0400)
committerDmitry Stogov <dmitry@zend.com>
Tue, 19 Mar 2013 11:45:48 +0000 (15:45 +0400)
Zend/tests/bug64239_1.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c

diff --git a/Zend/tests/bug64239_1.phpt b/Zend/tests/bug64239_1.phpt
new file mode 100644 (file)
index 0000000..fe58cbd
--- /dev/null
@@ -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"
+}
index 1e85785c4005b8dbda90e78c44da8fbe5ff1fde0..dcb18182e1dd53d4d4c1b229267991830cc1e957 100644 (file)
@@ -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 *);