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) diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 9f8e9b77003b..79ea3703ead6 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 a7e26711cd17..983299c0a9d8 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1723,9 +1723,14 @@ static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int ind { 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->{'---'})