Skip to content

Commit 202e587

Browse files
committed
Forbid variable bindings inside | pattern
1 parent 0926e00 commit 202e587

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
Must not bind to variables in | pattern
3+
--FILE--
4+
<?php
5+
var_dump(42 is $foo|$bar);
6+
?>
7+
--EXPECTF--
8+
Fatal error: Must not bind to variables inside | pattern 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+
Must not bind to variables in | pattern
3+
--FILE--
4+
<?php
5+
var_dump(42 is 42|(43 & $bar));
6+
?>
7+
--EXPECTF--
8+
Fatal error: Must not bind to variables inside | pattern in %s on line %d

Zend/zend_compile.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6600,13 +6600,24 @@ static void zend_compile_and_pattern(zend_ast **ast_ptr)
66006600
verify_parenthesized_compound_pattern(ast_ptr, ZEND_AST_OR_PATTERN);
66016601
}
66026602

6603+
struct zend_compile_pattern_context {
6604+
bool inside_or_pattern;
6605+
};
6606+
66036607
static void zend_compile_pattern(zend_ast **ast_ptr, void *context)
66046608
{
66056609
zend_ast *ast = *ast_ptr;
66066610
if (ast == NULL || ast->kind == ZEND_AST_ZVAL) {
66076611
return;
66086612
}
66096613

6614+
struct zend_compile_pattern_context *pattern_context = context;
6615+
struct zend_compile_pattern_context tmp_context = {0};
6616+
if (!pattern_context) {
6617+
pattern_context = &tmp_context;
6618+
}
6619+
bool prev_inside_or_pattern = pattern_context->inside_or_pattern;
6620+
66106621
switch (ast->kind) {
66116622
case ZEND_AST_OBJECT_PATTERN:
66126623
zend_compile_object_pattern(ast_ptr);
@@ -6615,6 +6626,9 @@ static void zend_compile_pattern(zend_ast **ast_ptr, void *context)
66156626
zend_compile_type_pattern(ast_ptr);
66166627
break;
66176628
case ZEND_AST_BINDING_PATTERN:
6629+
if (pattern_context->inside_or_pattern) {
6630+
zend_throw_exception(zend_ce_compile_error, "Must not bind to variables inside | pattern", 0);
6631+
}
66186632
zend_compile_binding_pattern(ast_ptr);
66196633
break;
66206634
case ZEND_AST_ARRAY_PATTERN:
@@ -6624,14 +6638,16 @@ static void zend_compile_pattern(zend_ast **ast_ptr, void *context)
66246638
zend_compile_class_const_pattern(ast_ptr);
66256639
break;
66266640
case ZEND_AST_OR_PATTERN:
6641+
pattern_context->inside_or_pattern = true;
66276642
zend_compile_or_pattern(ast_ptr);
66286643
break;
66296644
case ZEND_AST_AND_PATTERN:
66306645
zend_compile_and_pattern(ast_ptr);
66316646
break;
66326647
}
66336648

6634-
zend_ast_apply(ast, zend_compile_pattern, context);
6649+
zend_ast_apply(ast, zend_compile_pattern, pattern_context);
6650+
pattern_context->inside_or_pattern = prev_inside_or_pattern;
66356651
}
66366652

66376653
static void zend_compile_is(znode *result, zend_ast *ast)

0 commit comments

Comments
 (0)