Skip to content

Commit 08b7539

Browse files
committed
Fix syntax error when dnf type in parens after readonly
Fixes GH-9500 Closes GH-9512
1 parent 8b63274 commit 08b7539

File tree

5 files changed

+71
-9
lines changed

5 files changed

+71
-9
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.2.0RC2
44

5+
- Core:
6+
. Fixed bug GH-9500 (Using dnf type with parentheses after readonly keyword
7+
results in a parse error). (ilutov)
8+
59
- Opcache:
610
. Fixed bug GH-9259 (opcache.interned_strings_buffer setting integer
711
overflow). (Arnaud)

Zend/tests/gh9500.phpt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Bug GH-9500: Disjunctive Normal Form Types - readonly property followed by (
3+
--FILE--
4+
<?php
5+
class Dnf
6+
{
7+
var A|(B&C) $a;
8+
var (B&C)|A $b;
9+
private A|(B&C) $c;
10+
private (B&C)|A $d;
11+
static A|(B&C) $e;
12+
static (B&C)|A $f;
13+
private static A|(B&C) $g;
14+
private static (B&C)|A $h;
15+
readonly private A|(B&C) $i;
16+
readonly private (B&C)|A $j;
17+
readonly A|(B&C) $k;
18+
readonly (B&C)|A $l;
19+
private readonly A|(B&C) $m;
20+
private readonly (B&C)|A $n;
21+
}
22+
?>
23+
DONE
24+
--EXPECT--
25+
DONE

Zend/tests/readonly_function.phpt

+26-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,34 @@ function readonly() {
77
echo "Hi!\n";
88
}
99

10+
class A {
11+
const readonly = 'Const hi!';
12+
13+
static function readonly() {
14+
echo "Static hi!\n";
15+
}
16+
}
17+
18+
class B {
19+
public $readonly = 'Prop hi!';
20+
21+
function readonly() {
22+
echo "Instance hi!\n";
23+
}
24+
}
25+
26+
$b = new B();
27+
1028
readonly();
11-
readonly ();
29+
echo A::readonly, "\n";
30+
A::readonly();
31+
$b->readonly();
32+
echo $b->readonly, "\n";
1233

1334
?>
1435
--EXPECT--
1536
Hi!
16-
Hi!
37+
Const hi!
38+
Static hi!
39+
Instance hi!
40+
Prop hi!

Zend/zend_language_parser.y

+16-1
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
278278
%type <ast> attribute_decl attribute attributes attribute_group namespace_declaration_name
279279
%type <ast> match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list
280280
%type <ast> enum_declaration_statement enum_backing_type enum_case enum_case_expr
281+
%type <ast> function_name
281282

282283
%type <num> returns_ref function fn is_reference is_variadic variable_modifiers
283284
%type <num> method_modifiers non_empty_member_modifiers member_modifier
@@ -560,8 +561,17 @@ unset_variable:
560561
variable { $$ = zend_ast_create(ZEND_AST_UNSET, $1); }
561562
;
562563

564+
function_name:
565+
T_STRING { $$ = $1; }
566+
| T_READONLY {
567+
zval zv;
568+
if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; }
569+
$$ = zend_ast_create_zval(&zv);
570+
}
571+
;
572+
563573
function_declaration_statement:
564-
function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type
574+
function returns_ref function_name backup_doc_comment '(' parameter_list ')' return_type
565575
backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
566576
{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4,
567577
zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; }
@@ -1270,6 +1280,11 @@ lexical_var:
12701280
function_call:
12711281
name argument_list
12721282
{ $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
1283+
| T_READONLY argument_list {
1284+
zval zv;
1285+
if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; }
1286+
$$ = zend_ast_create(ZEND_AST_CALL, zend_ast_create_zval(&zv), $2);
1287+
}
12731288
| class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
12741289
{ $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
12751290
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list

Zend/zend_language_scanner.l

-6
Original file line numberDiff line numberDiff line change
@@ -1729,12 +1729,6 @@ NEWLINE ("\r"|"\n"|"\r\n")
17291729
RETURN_TOKEN_WITH_IDENT(T_READONLY);
17301730
}
17311731

1732-
/* Don't treat "readonly(" as a keyword, to allow using it as a function name. */
1733-
<ST_IN_SCRIPTING>"readonly"[ \n\r\t]*"(" {
1734-
yyless(strlen("readonly"));
1735-
RETURN_TOKEN_WITH_STR(T_STRING, 0);
1736-
}
1737-
17381732
<ST_IN_SCRIPTING>"unset" {
17391733
RETURN_TOKEN_WITH_IDENT(T_UNSET);
17401734
}

0 commit comments

Comments
 (0)