Skip to content

Commit

Permalink
Reject assigning command call without parentheses
Browse files Browse the repository at this point in the history
Fixes: ruby#3106
  • Loading branch information
ydah committed Dec 3, 2024
1 parent 3167699 commit b045ab4
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -20895,6 +20895,23 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t *
}
}

static void
validate_local_variable_assignment_with_call(pm_parser_t *parser, pm_node_t *node) {
if (PM_NODE_TYPE_P(node, PM_LOCAL_VARIABLE_WRITE_NODE)) {
pm_local_variable_write_node_t* cast = (pm_local_variable_write_node_t *)node;
if (PM_NODE_TYPE_P(cast->value, PM_CALL_NODE)) {
pm_call_node_t *call_node = (pm_call_node_t *)cast->value;
if (call_node->arguments != NULL) {
if (call_node->opening_loc.start == NULL) {
pm_node_t *arguments = (pm_node_t *)call_node->arguments;
PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, arguments, PM_ERR_LAMBDA_OPEN);
PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, arguments, PM_ERR_EXPECT_LPAREN_REQ_PARAMETER);
}
}
}
}
}

static inline pm_node_t *
parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, uint16_t depth) {
pm_token_t token = parser->current;
Expand Down Expand Up @@ -21317,13 +21334,17 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
parser_lex(parser);

pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
validate_local_variable_assignment_with_call(parser, node);
validate_local_variable_assignment_with_call(parser, right);
return (pm_node_t *) pm_and_node_create(parser, node, &token, right);
}
case PM_TOKEN_KEYWORD_OR:
case PM_TOKEN_PIPE_PIPE: {
parser_lex(parser);

pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
validate_local_variable_assignment_with_call(parser, node);
validate_local_variable_assignment_with_call(parser, right);
return (pm_node_t *) pm_or_node_create(parser, node, &token, right);
}
case PM_TOKEN_EQUAL_TILDE: {
Expand Down Expand Up @@ -21542,13 +21563,15 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
parser_lex(parser);

pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_IF_PREDICATE, (uint16_t) (depth + 1));
validate_local_variable_assignment_with_call(parser, predicate);
return (pm_node_t *) pm_if_node_modifier_create(parser, node, &keyword, predicate);
}
case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: {
pm_token_t keyword = parser->current;
parser_lex(parser);

pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_UNLESS_PREDICATE, (uint16_t) (depth + 1));
validate_local_variable_assignment_with_call(parser, predicate);
return (pm_node_t *) pm_unless_node_modifier_create(parser, node, &keyword, predicate);
}
case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 and a = p 2
^ expected a `do` keyword or a `{` to open the lambda block
^ expected a `(` to start a required parameter

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 if a = p 2
^ expected a `do` keyword or a `{` to open the lambda block
^ expected a `(` to start a required parameter

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 or a = p 2
^ expected a `do` keyword or a `{` to open the lambda block
^ expected a `(` to start a required parameter

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 unless a = p 2
^ expected a `do` keyword or a `{` to open the lambda block
^ expected a `(` to start a required parameter

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a = p 1 and 2
^ expected a `do` keyword or a `{` to open the lambda block
^ expected a `(` to start a required parameter

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a = p 1 or 2
^ expected a `do` keyword or a `{` to open the lambda block
^ expected a `(` to start a required parameter

0 comments on commit b045ab4

Please sign in to comment.