Fix syntax error when dnf type in parens after readonly

Fixes GH-9500
Closes GH-9512
This commit is contained in:
Ilija Tovilo 2022-09-08 17:41:53 +02:00
parent 8b632749d7
commit 08b7539583
No known key found for this signature in database
GPG Key ID: A4F5D403F118200A
5 changed files with 71 additions and 9 deletions

4
NEWS
View File

@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.2.0RC2
- Core:
. Fixed bug GH-9500 (Using dnf type with parentheses after readonly keyword
results in a parse error). (ilutov)
- Opcache:
. Fixed bug GH-9259 (opcache.interned_strings_buffer setting integer
overflow). (Arnaud)

25
Zend/tests/gh9500.phpt Normal file
View File

@ -0,0 +1,25 @@
--TEST--
Bug GH-9500: Disjunctive Normal Form Types - readonly property followed by (
--FILE--
<?php
class Dnf
{
var A|(B&C) $a;
var (B&C)|A $b;
private A|(B&C) $c;
private (B&C)|A $d;
static A|(B&C) $e;
static (B&C)|A $f;
private static A|(B&C) $g;
private static (B&C)|A $h;
readonly private A|(B&C) $i;
readonly private (B&C)|A $j;
readonly A|(B&C) $k;
readonly (B&C)|A $l;
private readonly A|(B&C) $m;
private readonly (B&C)|A $n;
}
?>
DONE
--EXPECT--
DONE

View File

@ -7,10 +7,34 @@ function readonly() {
echo "Hi!\n";
}
class A {
const readonly = 'Const hi!';
static function readonly() {
echo "Static hi!\n";
}
}
class B {
public $readonly = 'Prop hi!';
function readonly() {
echo "Instance hi!\n";
}
}
$b = new B();
readonly();
readonly ();
echo A::readonly, "\n";
A::readonly();
$b->readonly();
echo $b->readonly, "\n";
?>
--EXPECT--
Hi!
Hi!
Const hi!
Static hi!
Instance hi!
Prop hi!

View File

@ -278,6 +278,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> attribute_decl attribute attributes attribute_group namespace_declaration_name
%type <ast> match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list
%type <ast> enum_declaration_statement enum_backing_type enum_case enum_case_expr
%type <ast> function_name
%type <num> returns_ref function fn is_reference is_variadic variable_modifiers
%type <num> method_modifiers non_empty_member_modifiers member_modifier
@ -560,8 +561,17 @@ unset_variable:
variable { $$ = zend_ast_create(ZEND_AST_UNSET, $1); }
;
function_name:
T_STRING { $$ = $1; }
| T_READONLY {
zval zv;
if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; }
$$ = zend_ast_create_zval(&zv);
}
;
function_declaration_statement:
function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type
function returns_ref function_name backup_doc_comment '(' parameter_list ')' return_type
backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4,
zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; }
@ -1270,6 +1280,11 @@ lexical_var:
function_call:
name argument_list
{ $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
| T_READONLY argument_list {
zval zv;
if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; }
$$ = zend_ast_create(ZEND_AST_CALL, zend_ast_create_zval(&zv), $2);
}
| class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
{ $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list

View File

@ -1729,12 +1729,6 @@ NEWLINE ("\r"|"\n"|"\r\n")
RETURN_TOKEN_WITH_IDENT(T_READONLY);
}
/* Don't treat "readonly(" as a keyword, to allow using it as a function name. */
<ST_IN_SCRIPTING>"readonly"[ \n\r\t]*"(" {
yyless(strlen("readonly"));
RETURN_TOKEN_WITH_STR(T_STRING, 0);
}
<ST_IN_SCRIPTING>"unset" {
RETURN_TOKEN_WITH_IDENT(T_UNSET);
}