From 6f41bfd1c7da2a0b536a85c17d1e58a8a3a8b58a Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:29:29 +0100 Subject: [PATCH 1/7] Export visibility for promoted property --- Zend/zend_ast.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d33747412ef..ddfc798ae6e 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2558,6 +2558,7 @@ simple_list: if (ast->child[3]) { zend_ast_export_attributes(str, ast->child[3], indent, 0); } + zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP); if (ast->child[0]) { zend_ast_export_type(str, ast->child[0], indent); smart_str_appendc(str, ' '); From 6920aa2ae63ad1ac2e6d9855ccf693d4d80fb0b7 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:29:51 +0100 Subject: [PATCH 2/7] Extract hook export code --- Zend/zend_ast.c | 89 +++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index ddfc798ae6e..d2551ddfb4d 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1744,6 +1744,51 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in zend_ast_export_ns_name(str, ast, 0, indent); } +static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *hook_list, int indent) +{ + smart_str_appends(str, " {"); + smart_str_appendc(str, '\n'); + indent++; + zend_ast_export_indent(str, indent); + + for (uint32_t i = 0; i < hook_list->children; i++) { + zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; + zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); + if (hook->flags & ZEND_ACC_FINAL) { + smart_str_appends(str, "final "); + } + switch (i) { + case ZEND_PROPERTY_HOOK_GET: + smart_str_appends(str, "get"); + break; + case ZEND_PROPERTY_HOOK_SET: + smart_str_appends(str, "set"); + break; + } + zend_ast *body = hook->child[2]; + if (body == NULL) { + smart_str_appendc(str, ';'); + } else if (body->kind == ZEND_AST_PROPERTY_HOOK_SHORT_BODY) { + smart_str_appends(str, " => "); + zend_ast_export_ex(str, body->child[0], 0, indent); + smart_str_appendc(str, ';'); + } else { + smart_str_appends(str, " {\n"); + zend_ast_export_stmt(str, body, indent + 1); + zend_ast_export_indent(str, indent); + smart_str_appendc(str, '}'); + } + if (i < (hook_list->children - 1)) { + smart_str_appendc(str, '\n'); + zend_ast_export_indent(str, indent); + } + } + smart_str_appendc(str, '\n'); + indent--; + zend_ast_export_indent(str, indent); + smart_str_appendc(str, '}'); +} + #define BINARY_OP(_op, _p, _pl, _pr) do { \ op = _op; \ p = _p; \ @@ -2389,49 +2434,7 @@ simple_list: } if (ast->child[3]) { - zend_ast_list *hook_list = zend_ast_get_list(ast->child[3]); - - smart_str_appends(str, " {"); - smart_str_appendc(str, '\n'); - indent++; - zend_ast_export_indent(str, indent); - - for (uint32_t i = 0; i < hook_list->children; i++) { - zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; - zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); - if (hook->flags & ZEND_ACC_FINAL) { - smart_str_appends(str, "final "); - } - switch (i) { - case ZEND_PROPERTY_HOOK_GET: - smart_str_appends(str, "get"); - break; - case ZEND_PROPERTY_HOOK_SET: - smart_str_appends(str, "set"); - break; - } - zend_ast *body = hook->child[2]; - if (body == NULL) { - smart_str_appendc(str, ';'); - } else if (body->kind == ZEND_AST_PROPERTY_HOOK_SHORT_BODY) { - smart_str_appends(str, " => "); - zend_ast_export_ex(str, body->child[0], 0, indent); - smart_str_appendc(str, ';'); - } else { - smart_str_appends(str, " {\n"); - zend_ast_export_stmt(str, body, indent + 1); - zend_ast_export_indent(str, indent); - smart_str_appendc(str, '}'); - } - if (i < (hook_list->children - 1)) { - smart_str_appendc(str, '\n'); - zend_ast_export_indent(str, indent); - } - } - smart_str_appendc(str, '\n'); - indent--; - zend_ast_export_indent(str, indent); - smart_str_appendc(str, '}'); + zend_ast_export_hook_list(str, zend_ast_get_list(ast->child[3]), indent); } break; case ZEND_AST_CONST_ELEM: From 0cba85b54da799947f80d2616b4a0bcc05857d55 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:31:26 +0100 Subject: [PATCH 3/7] Fix property hook name mismatch --- Zend/zend_ast.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d2551ddfb4d..30b067a5ba7 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1757,14 +1757,7 @@ static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *h if (hook->flags & ZEND_ACC_FINAL) { smart_str_appends(str, "final "); } - switch (i) { - case ZEND_PROPERTY_HOOK_GET: - smart_str_appends(str, "get"); - break; - case ZEND_PROPERTY_HOOK_SET: - smart_str_appends(str, "set"); - break; - } + smart_str_append(str, hook->name); zend_ast *body = hook->child[2]; if (body == NULL) { smart_str_appendc(str, ';'); From 3f0f7ab7df78067bb12a17c10b0b92008152fde3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:43:23 +0100 Subject: [PATCH 4/7] Print hooks in parameter exports --- Zend/zend_ast.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 30b067a5ba7..29b82502485 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2567,7 +2567,14 @@ simple_list: } smart_str_appendc(str, '$'); zend_ast_export_name(str, ast->child[1], 0, indent); - APPEND_DEFAULT_VALUE(2); + if (ast->child[2]) { + smart_str_appends(str, " = "); + zend_ast_export_ex(str, ast->child[2], 0, indent); + } + if (ast->child[5]) { + zend_ast_export_hook_list(str, zend_ast_get_list(ast->child[5]), indent); + } + break; case ZEND_AST_ENUM_CASE: if (ast->child[3]) { zend_ast_export_attributes(str, ast->child[3], indent, 1); From d4778224cae2db6b50213aadf336bc132ec5f316 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:43:38 +0100 Subject: [PATCH 5/7] Add test for GH-17101 --- Zend/tests/property_hooks/gh17101.phpt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Zend/tests/property_hooks/gh17101.phpt diff --git a/Zend/tests/property_hooks/gh17101.phpt b/Zend/tests/property_hooks/gh17101.phpt new file mode 100644 index 00000000000..3ab53fb75da --- /dev/null +++ b/Zend/tests/property_hooks/gh17101.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-17101 (AST->string does not reproduce constructor property promotion correctly) +--FILE-- + $this->boolVal = 1;} ) {} + }); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +assert(false && new class { + public function __construct(#[Foo] public private(set) bool $boolVal = false { + final set => $this->boolVal = 1; + }) { + } + +}) From 18d47cf63fc727127360daad76dbcd50b607b0fe Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:07:14 +0100 Subject: [PATCH 6/7] [ci skip] News for GH-17101 --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 7ac43360536..acd439d9bbf 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ PHP NEWS . Fixed bug GH-17106 (ZEND_MATCH_ERROR misoptimization). (ilutov) . Fixed bug GH-17162 (zend_array_try_init() with dtor can cause engine UAF). (nielsdos) + . Fixed bug GH-17101 (AST->string does not reproduce constructor property + promotion correctly). (nielsdos) - DBA: . Skip test if inifile is disabled. (orlitzky) From 160a4a65ad70bc67e7a0ebc04d375ebab3452bb2 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:29:29 +0100 Subject: [PATCH 7/7] Export visibility for promoted property (8.3) --- NEWS | 2 ++ Zend/zend_ast.c | 1 + 2 files changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 6ac803f4639..856e8845f75 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Fixed bug GH-17106 (ZEND_MATCH_ERROR misoptimization). (ilutov) . Fixed bug GH-17162 (zend_array_try_init() with dtor can cause engine UAF). (nielsdos) + . Fixed bug GH-17101 (AST->string does not reproduce constructor property + promotion correctly). (nielsdos) - DBA: . Skip test if inifile is disabled. (orlitzky) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 525d9dfe9a7..bf602449e5e 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2443,6 +2443,7 @@ simple_list: if (ast->child[3]) { zend_ast_export_attributes(str, ast->child[3], indent, 0); } + zend_ast_export_visibility(str, ast->attr); if (ast->child[0]) { zend_ast_export_type(str, ast->child[0], indent); smart_str_appendc(str, ' ');