Skip to content

Commit 060bcc8

Browse files
authored
Check a token after targets more strictly (#1878)
Fix #1832
1 parent 7e6aa17 commit 060bcc8

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

src/prism.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10692,8 +10692,12 @@ static pm_node_t *
1069210692
parse_target_validate(pm_parser_t *parser, pm_node_t *target) {
1069310693
pm_node_t *result = parse_target(parser, target);
1069410694

10695-
// Ensure that we have either an = or a ) after the targets.
10696-
if (!match3(parser, PM_TOKEN_EQUAL, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_KEYWORD_IN)) {
10695+
// Ensure that we have one of an =, an 'in' in for indexes, and a ')' in parens after the targets.
10696+
if (
10697+
!match1(parser, PM_TOKEN_EQUAL) &&
10698+
!(context_p(parser, PM_CONTEXT_FOR_INDEX) && match1(parser, PM_TOKEN_KEYWORD_IN)) &&
10699+
!(context_p(parser, PM_CONTEXT_PARENS) && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT))
10700+
) {
1069710701
pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED);
1069810702
}
1069910703

@@ -13746,7 +13750,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
1374613750
// Otherwise, we're going to parse the first statement in the list
1374713751
// of statements within the parentheses.
1374813752
pm_accepts_block_stack_push(parser, true);
13753+
context_push(parser, PM_CONTEXT_PARENS);
1374913754
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_CANNOT_PARSE_EXPRESSION);
13755+
context_pop(parser);
1375013756

1375113757
// Determine if this statement is followed by a terminator. In the
1375213758
// case of a single statement, this is fine. But in the case of

test/prism/errors_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,11 @@ def test_invalid_multi_target
12251225
assert_error_messages "Foo::foo,", error_messages
12261226
assert_error_messages "foo[foo],", error_messages
12271227
assert_error_messages "(foo, bar)", error_messages
1228+
assert_error_messages "foo((foo, bar))", error_messages
1229+
assert_error_messages "foo((*))", error_messages
1230+
assert_error_messages "foo(((foo, bar), *))", error_messages
1231+
assert_error_messages "(foo, bar) + 1", error_messages
1232+
assert_error_messages "(foo, bar) in baz", error_messages
12281233
end
12291234

12301235
def test_call_with_block_and_write

0 commit comments

Comments
 (0)