Skip to content

Commit 36bd571

Browse files
committed
Require parentheses for nested compound patterns
1 parent 6d2b344 commit 36bd571

File tree

5 files changed

+51
-1
lines changed

5 files changed

+51
-1
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
Nested compound patterns require parentheses
3+
--FILE--
4+
<?php
5+
var_dump(42 is Foo|Bar&Baz);
6+
?>
7+
--EXPECTF--
8+
Fatal error: Nested compound pattern must be parenthesized in %s on line %d
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
Nested compound patterns require parentheses
3+
--FILE--
4+
<?php
5+
var_dump(42 is Foo&Bar|Baz);
6+
?>
7+
--EXPECTF--
8+
Fatal error: Nested compound pattern must be parenthesized in %s on line %d

Zend/zend_compile.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6196,6 +6196,27 @@ static void zend_compile_array_pattern(zend_ast **ast_ptr)
61966196
}
61976197
}
61986198

6199+
static void verify_parenthesized_compound_pattern(zend_ast **ast_ptr, zend_ast_kind kind)
6200+
{
6201+
zend_ast *ast = *ast_ptr;
6202+
zend_ast *lhs = ast->child[0];
6203+
zend_ast *rhs = ast->child[1];
6204+
if ((lhs->kind == kind && !(lhs->attr & ZEND_PARENTHESIZED_PATTERN))
6205+
|| (rhs->kind == kind && !(rhs->attr & ZEND_PARENTHESIZED_PATTERN))) {
6206+
zend_throw_exception(zend_ce_compile_error, "Nested compound pattern must be parenthesized", 0);
6207+
}
6208+
}
6209+
6210+
static void zend_compile_or_pattern(zend_ast **ast_ptr)
6211+
{
6212+
verify_parenthesized_compound_pattern(ast_ptr, ZEND_AST_AND_PATTERN);
6213+
}
6214+
6215+
static void zend_compile_and_pattern(zend_ast **ast_ptr)
6216+
{
6217+
verify_parenthesized_compound_pattern(ast_ptr, ZEND_AST_OR_PATTERN);
6218+
}
6219+
61996220
static void zend_compile_pattern(zend_ast **ast_ptr, void *context)
62006221
{
62016222
zend_ast *ast = *ast_ptr;
@@ -6219,6 +6240,12 @@ static void zend_compile_pattern(zend_ast **ast_ptr, void *context)
62196240
case ZEND_AST_CLASS_CONST_PATTERN:
62206241
zend_compile_class_const_pattern(ast_ptr);
62216242
break;
6243+
case ZEND_AST_OR_PATTERN:
6244+
zend_compile_or_pattern(ast_ptr);
6245+
break;
6246+
case ZEND_AST_AND_PATTERN:
6247+
zend_compile_and_pattern(ast_ptr);
6248+
break;
62226249
}
62236250

62246251
zend_ast_apply(ast, zend_compile_pattern, context);

Zend/zend_compile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,8 @@ static zend_always_inline bool zend_check_arg_send_type(const zend_function *zf,
11261126
/* Attribute for ternary inside parentheses */
11271127
#define ZEND_PARENTHESIZED_CONDITIONAL 1
11281128

1129+
#define ZEND_PARENTHESIZED_PATTERN 1
1130+
11291131
/* For "use" AST nodes and the seen symbol table */
11301132
#define ZEND_SYMBOL_CLASS (1<<0)
11311133
#define ZEND_SYMBOL_FUNCTION (1<<1)

Zend/zend_language_parser.y

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,12 @@ atomic_pattern:
12931293
| binding_pattern { $$ = $1; }
12941294
| class_const_pattern { $$ = $1; }
12951295
| T_UNDERSCORE { $$ = zend_ast_create(ZEND_AST_WILDCARD_PATTERN); }
1296-
| '(' pattern ')' { $$ = $2; }
1296+
| '(' pattern ')' {
1297+
$$ = $2;
1298+
if ($$->kind == ZEND_AST_OR_PATTERN || $$->kind == ZEND_AST_AND_PATTERN) {
1299+
$$->attr = ZEND_PARENTHESIZED_CONDITIONAL;
1300+
}
1301+
}
12971302
;
12981303

12991304
compound_pattern:

0 commit comments

Comments
 (0)