From 0d87c30070954885e76763353d4b14c9548eb8f2 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Fri, 12 Nov 2021 16:31:40 -0600 Subject: [PATCH] Ensure zend_ast_fetch_class uses scope it is provided to fetch classes. Addresses bug 81611. --- Zend/zend_ast.c | 2 +- Zend/zend_execute.h | 1 + Zend/zend_execute_API.c | 18 +++++++-- ext/reflection/tests/bug81611.phpt | 64 ++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 ext/reflection/tests/bug81611.phpt diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index a064927f93a87..0d69bfbaca369 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -482,7 +482,7 @@ static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) { zend_class_entry *zend_ast_fetch_class(zend_ast *ast, zend_class_entry *scope) { - return zend_fetch_class(zend_ast_get_str(ast), ast->attr | ZEND_FETCH_CLASS_EXCEPTION); + return zend_fetch_class_with_scope(zend_ast_get_str(ast), ast->attr | ZEND_FETCH_CLASS_EXCEPTION, scope); } ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 278afc9c10fa3..d13087a5b0264 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -349,6 +349,7 @@ ZEND_API void zend_set_timeout(zend_long seconds, bool reset_signals); ZEND_API void zend_unset_timeout(void); ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void); ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type); +ZEND_API zend_class_entry *zend_fetch_class_with_scope(zend_string *class_name, int fetch_type, zend_class_entry *scope); ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, int fetch_type); ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7d870530b1522..62f0e5ddd26d2 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1479,21 +1479,25 @@ void zend_unset_timeout(void) /* {{{ */ } /* }}} */ -zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */ +zend_class_entry *zend_fetch_class_with_scope(zend_string *class_name, int fetch_type, zend_class_entry *scope) /* {{{ */ { - zend_class_entry *ce, *scope; + zend_class_entry *ce; int fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK; check_fetch_type: switch (fetch_sub_type) { case ZEND_FETCH_CLASS_SELF: - scope = zend_get_executed_scope(); + if (scope == NULL) { + scope = zend_get_executed_scope(); + } if (UNEXPECTED(!scope)) { zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active"); } return scope; case ZEND_FETCH_CLASS_PARENT: - scope = zend_get_executed_scope(); + if (scope == NULL) { + scope = zend_get_executed_scope(); + } if (UNEXPECTED(!scope)) { zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active"); return NULL; @@ -1535,6 +1539,12 @@ zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* { } /* }}} */ +zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */ +{ + return zend_fetch_class_with_scope(class_name, fetch_type, NULL); +} +/* }}} */ + zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *key, int fetch_type) /* {{{ */ { zend_class_entry *ce = zend_lookup_class_ex(class_name, key, fetch_type); diff --git a/ext/reflection/tests/bug81611.phpt b/ext/reflection/tests/bug81611.phpt new file mode 100644 index 0000000000000..94bebf359cbef --- /dev/null +++ b/ext/reflection/tests/bug81611.phpt @@ -0,0 +1,64 @@ +--TEST-- +Reflection Bug #81611 (ArgumentCountError when getting default value from ReflectionParameter with new) +--FILE-- +getMethod($method)->getParameters(); + + foreach ($params as $param) { + echo "isDefaultValueAvailable:\n"; + var_dump($param->isDefaultValueAvailable()); + + echo "isDefaultValueConstant:\n"; + var_dump($param->isDefaultValueConstant()); + + echo "getDefaultValueConstantName:\n"; + var_dump($param->getDefaultValueConstantName()); + + echo "getDefaultValue:\n"; + var_dump($param->getDefaultValue()); + + echo "\n"; + } +} +?> +--EXPECT-- +isDefaultValueAvailable: +bool(true) +isDefaultValueConstant: +bool(false) +getDefaultValueConstantName: +NULL +getDefaultValue: +object(Foo)#2 (0) { +} + +isDefaultValueAvailable: +bool(true) +isDefaultValueConstant: +bool(false) +getDefaultValueConstantName: +NULL +getDefaultValue: +object(Bar)#3 (0) { +}