From: Dmitry Stogov Date: Tue, 16 Jun 2015 10:29:17 +0000 (+0300) Subject: Fixed bug #69802 (Reflection on Closure::__invoke borks type hint class name) (onr... X-Git-Tag: php-7.0.0alpha2~2^2~117 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3180b8e100285e5bd9088e9981608dfd14f6ff27;p=php Fixed bug #69802 (Reflection on Closure::__invoke borks type hint class name) (onr more problem) --- diff --git a/Zend/tests/bug69802_2.phpt b/Zend/tests/bug69802_2.phpt new file mode 100644 index 0000000000..a2de302707 --- /dev/null +++ b/Zend/tests/bug69802_2.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #69802 (Reflection on Closure::__invoke borks type hint class name) +--FILE-- +getClosure(); +$r = new ReflectionMethod($f, '__invoke'); +var_dump($r->getParameters()[0]->getClass()); +?> +--EXPECT-- +object(ReflectionClass)#4 (1) { + ["name"]=> + string(11) "Traversable" +} diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 2d38fb2f4c..b28810a236 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -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; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 195ea70fc0..4a2d7ccfa3 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -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);