From 2cfb028e22f807d859823d040a77c912e8afb996 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 1 Sep 2022 23:17:20 +0200 Subject: [PATCH] Fix class name FQN when AST dumping new and class const Fixes GH-9447 Closes GH-9462 --- NEWS | 2 ++ Zend/zend_ast.c | 2 +- Zend/zend_compile.c | 4 ++-- Zend/zend_compile.h | 3 +++ ext/reflection/tests/gh9447.phpt | 39 ++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 ext/reflection/tests/gh9447.phpt diff --git a/NEWS b/NEWS index a5dcc78b668..f2637985143 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS (Tim Starling) . Fixed bug GH-9361 (Segmentation fault on script exit #9379). (cmb, Christian Schneider) + . Fixed bug GH-9447 (Invalid class FQN emitted by AST dump for new and class + constants in constant expressions). (ilutov) - DOM: . Fixed bug #79451 (DOMDocument->replaceChild on doctype causes double free). diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d0a180ee6a9..07cb9c5fbb7 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_with_scope(zend_ast_get_str(ast), ast->attr | ZEND_FETCH_CLASS_EXCEPTION, scope); + return zend_fetch_class_with_scope(zend_ast_get_str(ast), (ast->attr >> ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT) | 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_compile.c b/Zend/zend_compile.c index 4a49687415c..8157ea169c8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9738,8 +9738,8 @@ static void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */ zend_string_release_ex(class_name, 0); if (tmp != class_name) { zval *zv = zend_ast_get_zval(class_ast); - ZVAL_STR(zv, tmp); + class_ast->attr = ZEND_NAME_FQ; } } @@ -9834,7 +9834,7 @@ static void zend_compile_const_expr_new(zend_ast **ast_ptr) zval *class_ast_zv = zend_ast_get_zval(class_ast); zval_ptr_dtor_nogc(class_ast_zv); ZVAL_STR(class_ast_zv, class_name); - class_ast->attr = fetch_type; + class_ast->attr = fetch_type << ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT; } static void zend_compile_const_expr_args(zend_ast **ast_ptr) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index d396f3530a5..ac304ac7f6a 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -917,6 +917,9 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_NAME_NOT_FQ 1 #define ZEND_NAME_RELATIVE 2 +/* ZEND_FETCH_ flags in class name AST of new const expression must not clash with ZEND_NAME_ flags */ +#define ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT 2 + #define ZEND_TYPE_NULLABLE (1<<8) #define ZEND_ARRAY_SYNTAX_LIST 1 /* list() */ diff --git a/ext/reflection/tests/gh9447.phpt b/ext/reflection/tests/gh9447.phpt new file mode 100644 index 00000000000..9ee90832973 --- /dev/null +++ b/ext/reflection/tests/gh9447.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-9447: Invalid class FQN emitted by AST dump for new and class constants in constant expressions +--FILE-- +getParameters() as $p) { + echo $p, "\n"; +} + +?> +--EXPECT-- +Parameter #0 [ $a = \App\Bar::BAZ ] +Parameter #1 [ $b = new \App\Bar() ] +Parameter #2 [ $c = new parent() ] +Parameter #3 [ $d = new self() ] +Parameter #4 [ $e = new \App\Bar() ] +Parameter #5 [ $f = new \SomewhereElse\Qux() ] +Parameter #6 [ $g = new \App\Qux() ] +Parameter #7 [ $i = new \Qux() ]