-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Make "{$g{'h'}}"
emit fatal error and no incorrect deprecation notice in 8.2
#9264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make "{$g{'h'}}"
emit fatal error and no incorrect deprecation notice in 8.2
#9264
Conversation
Thank you @TysonAndre! I missed this conflict. |
To make a note of something I was confused about: The check when compiling the encapsulated variable list isn't checking the node kind (which can either be AST_DIM or AST_VAR or AST_ZVAL) The node kinds for AST_DIM were previously not overlapping (ZEND_ENCAPS_VAR_DOLLAR_CURLY != ZEND_DIM_ALTERNATIVE_SYNTAX) - the actual issue causing the deprecation notice is that nothing bothered to distinguish between ast_node->kind AST_VAR and AST_DIM (and any other/future flag types) when checking if the deprecation notice should be emitted. Still, having these bit flag values be entirely separate ranges seems like the most convenient Zend/zend_language_parser.y
1507: { $$ = zend_ast_create_ex(ZEND_AST_VAR, ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR, $2); }
1509: { $$ = zend_ast_create_ex(ZEND_AST_VAR, ZEND_ENCAPS_VAR_DOLLAR_CURLY, $2); }
1511: { $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_ENCAPS_VAR_DOLLAR_CURLY,
Zend/zend_compile.c
9626: if (encaps_var->attr & (ZEND_ENCAPS_VAR_DOLLAR_CURLY|ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR)) {
9627: if (encaps_var->attr & ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR) { // Zend/zend_compile.c
for (i = 0; i < list->children; i++) {
zend_ast *encaps_var = list->child[i];
if (encaps_var->attr & (ZEND_ENCAPS_VAR_DOLLAR_CURLY|ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR)) {
if (encaps_var->attr & ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR) {
zend_error(E_DEPRECATED, "Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead");
} else {
zend_error(E_DEPRECATED, "Using ${var} in strings is deprecated, use {$var} instead");
}
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the actual issue causing the deprecation notice is that nothing bothered to distinguish between ast_node->kind AST_VAR and AST_DIM (and any other/future flag types) when checking if the deprecation notice should be emitted.
In that case we should probably add this check too. Changing the flags might even be more confusing then than anything, as it makes it look like they can clash when they really can't. At least looking at the parser, it doesn't look like ZEND_AST_VAR
have any other flags.
if (encaps_var->kind == ZEND_AST_VAR && (encaps_var->attr & (ZEND_ENCAPS_VAR_DOLLAR_CURLY|ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR))) {
I had to double check, but it looks like it's safe to keep the values of the constants as is and just change the deprecation notice emitting logic to check kinds There's code related to nodes of type ZEND_DIM_IS (for isset handling) where it's set after the parse phase in zend_compile.c but that overlap won't matter. As far as I can tell, the overlap won't matter, because
// Zend/zend_language_parser.y
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
{ $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_ENCAPS_VAR_DOLLAR_CURLY,
zend_ast_create(ZEND_AST_VAR, $2), $4); } Zend/zend_ast.c
762: zend_fetch_dimension_const(result, &op1, &op2, (ast->attr & ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R);
Zend/zend_compile.c
10441: ast->child[0]->attr |= ZEND_DIM_IS;
10501: if ((ast->attr & ZEND_DIM_IS) && ast->child[0]->kind == ZEND_AST_DIM) {
10502: ast->child[0]->attr |= ZEND_DIM_IS; |
The ast node flag constants ZEND_DIM_ALTERNATIVE_SYNTAX and ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR node have identical values (1<<1), causing a deprecation notice to be incorrectly emitted before the fatal error for unsupported syntax. Only emit the deprecation notice if the ast_node kind is ZEND_AST_VAR. Fixes phpGH-9263
59f5ffc
to
e531959
Compare
`AST_PROP`/`AST_METHOD_CALL` and nullsafe variants can also be found in encapsulated strings - currently they have no flags but they may have flags in the future. This also clarifies that this deprecation warning can only happen for AST_VAR/AST_DIM nodes.
The ast node flag constants ZEND_DIM_ALTERNATIVE_SYNTAX and
ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR node have identical values (1<<1),
causing a deprecation notice to be incorrectly emitted before the fatal error
for unsupported syntax.
To fix this, check if the kind is the expected kind of
AST_VAR
/AST_DIM
associated with the flag being checked for. The node kind in encapsulated strings can also bePROP
/METHOD_CALL
, which currently have no flags, but explicitly check the kind to make the deprecation notice logic easier to reason about and less likely to break if flags are added.Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead
before the fatal errorFixes GH-9263
Followup to https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation in php 8.2