From 862b40496ae172e74b7906168bad6b0d2e81c5fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sat, 13 Jun 2026 15:10:41 +0200 Subject: [PATCH 1/2] zend_ast: Quote names of invalid variable names when exporting AST Fixes php/php-src#22292. --- Zend/tests/assert/expect_015.phpt | 2 +- Zend/zend_ast.c | 11 ++++++--- ext/standard/tests/assert/gh22292.phpt | 31 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 ext/standard/tests/assert/gh22292.phpt diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 695c4c166a83..35d755bc0508 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -304,7 +304,7 @@ assert(0 && ($a = function (): ?static { $x = "{$a}b"; $x = "{$a}b"; $x = " {$foo->bar} {${$foo->bar}} "; - $x = " ${---} "; + $x = " ${'---'} "; foo(); \foo(); namespace\foo(); diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 9df2320d5666..844d1919960b 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1415,9 +1415,14 @@ static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int pri { if (ast->kind == ZEND_AST_ZVAL) { zval *zv = zend_ast_get_zval(ast); - if (Z_TYPE_P(zv) == IS_STRING && - zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) { - smart_str_append(str, Z_STR_P(zv)); + if (Z_TYPE_P(zv) == IS_STRING) { + if (zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) { + smart_str_append(str, Z_STR_P(zv)); + } else { + smart_str_appends(str, "{'"); + zend_ast_export_str(str, Z_STR_P(zv)); + smart_str_appends(str, "'}"); + } return; } } else if (ast->kind == ZEND_AST_VAR) { diff --git a/ext/standard/tests/assert/gh22292.phpt b/ext/standard/tests/assert/gh22292.phpt new file mode 100644 index 000000000000..e3aa72bf231a --- /dev/null +++ b/ext/standard/tests/assert/gh22292.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-22292: AST pretty printing does not correctly handle invalid variable names +--FILE-- +getMessage(), PHP_EOL; +} + +try { + $f = new Foo(); + var_dump($f->{'---'}); + assert(!$f->{'---'}); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +string(3) "abc" +assert(!${'---'}) +string(3) "---" +assert(!$f->{'---'}) From 23fd54884de223b9f11c886e6e279fcd3e1035e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sun, 14 Jun 2026 12:38:49 +0200 Subject: [PATCH 2/2] NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index ac3381900831..eff542c0e46b 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,8 @@ PHP NEWS . Fixed bug GH-22046 (The unserialize function can lead to segfault when non-Serializable internal classes are serialized back with the C format). (kocsismate) + . Fixed bug GH-22292 (AST pretty printing does not correctly handle + invalid variable names). (timwolla) - BCMath: . Added NUL-byte validation to BCMath functions. (jorgsowa)