From d033d5c07a25ab36a9138f35a7a02f62822a9e4d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 12 Nov 2020 11:02:04 +0100 Subject: Fix reflection getDefaultValue() with user arg info The default value is part of the op_array in that case, but we have no way to access it. Fail gracefully. --- ext/reflection/php_reflection.c | 7 ++++++- .../tests/default_value_internal_userland_arginfo.phpt | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 7adcfc506a..2be0ab98db 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1432,6 +1432,10 @@ static void reflection_class_constant_factory(zend_string *name_str, zend_class_ static int get_parameter_default(zval *result, parameter_reference *param) { if (param->fptr->type == ZEND_INTERNAL_FUNCTION) { + if (param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO) { + /* We don't have a way to determine the default value for this case right now. */ + return FAILURE; + } return zend_get_default_from_internal_arg_info( result, (zend_internal_arg_info *) param->arg_info); } else { @@ -2717,7 +2721,8 @@ ZEND_METHOD(ReflectionParameter, isDefaultValueAvailable) GET_REFLECTION_OBJECT_PTR(param); if (param->fptr->type == ZEND_INTERNAL_FUNCTION) { - RETURN_BOOL(((zend_internal_arg_info*) (param->arg_info))->default_value); + RETURN_BOOL(!(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO) + && ((zend_internal_arg_info*) (param->arg_info))->default_value); } else { zval *default_value = get_default_from_recv((zend_op_array *)param->fptr, param->offset); RETURN_BOOL(default_value != NULL); diff --git a/ext/reflection/tests/default_value_internal_userland_arginfo.phpt b/ext/reflection/tests/default_value_internal_userland_arginfo.phpt index d2b0589cd1..b55a946379 100644 --- a/ext/reflection/tests/default_value_internal_userland_arginfo.phpt +++ b/ext/reflection/tests/default_value_internal_userland_arginfo.phpt @@ -6,6 +6,14 @@ $closure = function ($b = 0) {}; $ro = new ReflectionObject($closure); $rm = $ro->getMethod('__invoke'); echo $rm, "\n"; + +$rp = $rm->getParameters()[0]; +var_dump($rp->isDefaultValueAvailable()); +try { + var_dump($rp->getDefaultValue()); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECT-- Method [ public method __invoke ] { @@ -14,3 +22,6 @@ Method [ public method __invoke ] { Parameter #0 [ $b = ] } } + +bool(false) +Internal error: Failed to retrieve the default value -- cgit v1.2.1