]> granicus.if.org Git - php/commitdiff
Fixed bug #69802 (Reflection on Closure::__invoke borks type hint class name) (onr...
authorDmitry Stogov <dmitry@zend.com>
Tue, 16 Jun 2015 10:29:17 +0000 (13:29 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 16 Jun 2015 10:29:17 +0000 (13:29 +0300)
Zend/tests/bug69802_2.phpt [new file with mode: 0644]
Zend/zend_closures.c
ext/reflection/php_reflection.c

diff --git a/Zend/tests/bug69802_2.phpt b/Zend/tests/bug69802_2.phpt
new file mode 100644 (file)
index 0000000..a2de302
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #69802 (Reflection on Closure::__invoke borks type hint class name)
+--FILE--
+<?php
+$f = (new ReflectionFunction('iterator_to_array'))->getClosure();
+$r = new ReflectionMethod($f, '__invoke');
+var_dump($r->getParameters()[0]->getClass());
+?>
+--EXPECT--
+object(ReflectionClass)#4 (1) {
+  ["name"]=>
+  string(11) "Traversable"
+}
index 2d38fb2f4c15ef5bf2fc961d534022859a3acb3c..b28810a236aaec9c93ec301a92e82cd975d276a5 100644 (file)
@@ -214,7 +214,11 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* {
         * ZEND_ACC_USER_ARG_INFO flag to prevent invalid usage by Reflection */
        invoke->type = ZEND_INTERNAL_FUNCTION;
        invoke->internal_function.fn_flags =
-               ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_USER_ARG_INFO | (closure->func.common.fn_flags & keep_flags);
+               ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & keep_flags);
+       if (closure->func.type != ZEND_INTERNAL_FUNCTION || (closure->func.common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
+               invoke->internal_function.fn_flags |=
+                       ZEND_ACC_USER_ARG_INFO;
+       }
        invoke->internal_function.handler = ZEND_MN(Closure___invoke);
        invoke->internal_function.module = 0;
        invoke->internal_function.scope = zend_ce_closure;
@@ -488,7 +492,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
 
        closure = (zend_closure *)Z_OBJ_P(res);
 
-       closure->func = *func;
+       memcpy(&closure->func, func, func->type == ZEND_USER_FUNCTION ? sizeof(zend_op_array) : sizeof(zend_internal_function));
        closure->func.common.prototype = (zend_function*)closure;
        closure->func.common.fn_flags |= ZEND_ACC_CLOSURE;
 
index 195ea70fc041133a139d98fa3138c0df2e2c3d19..4a2d7ccfa38e1951605946b3efb4c4265ed48bb4 100644 (file)
@@ -2654,7 +2654,7 @@ ZEND_METHOD(reflection_parameter, getClass)
                        ce = ce->parent;
                } else {
                        if (param->fptr->type == ZEND_INTERNAL_FUNCTION &&
-                           (param->fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
+                           !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
                                zend_string *name = zend_string_init(class_name, class_name_len, 0);
                                ce = zend_lookup_class(name);
                                zend_string_release(name);