From d0d9699c27d0053baeb233de62fcd560cf9f584b Mon Sep 17 00:00:00 2001 From: ydah Date: Wed, 27 Nov 2024 19:31:29 +0900 Subject: [PATCH] Reject invalid operator after match predicate or after match required Partially fixes: #3171 --- src/prism.c | 27 +++++++++++++++++++ ...atch_predicate_after_and_with_opreator.txt | 3 +++ ...match_predicate_after_or_with_opreator.txt | 3 +++ ...h_predicate_after_rescue_with_opreator.txt | 3 +++ ...match_required_after_and_with_opreator.txt | 3 +++ .../match_required_after_or_with_opreator.txt | 3 +++ ...ch_required_after_rescue_with_opreator.txt | 3 +++ 7 files changed, 45 insertions(+) create mode 100644 test/prism/errors/match_predicate_after_and_with_opreator.txt create mode 100644 test/prism/errors/match_predicate_after_or_with_opreator.txt create mode 100644 test/prism/errors/match_predicate_after_rescue_with_opreator.txt create mode 100644 test/prism/errors/match_required_after_and_with_opreator.txt create mode 100644 test/prism/errors/match_required_after_or_with_opreator.txt create mode 100644 test/prism/errors/match_required_after_rescue_with_opreator.txt diff --git a/src/prism.c b/src/prism.c index b01f4df6dd..7e747203a6 100644 --- a/src/prism.c +++ b/src/prism.c @@ -21403,6 +21403,33 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t case PM_TOKEN_STAR: case PM_TOKEN_STAR_STAR: { parser_lex(parser); + pm_token_t operator = parser->previous; + switch (PM_NODE_TYPE(node)) { + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + if (PM_NODE_TYPE_P(cast->rescue_expression, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->rescue_expression, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + if (PM_NODE_TYPE_P(cast->right, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->right, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + if (PM_NODE_TYPE_P(cast->right, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->right, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + default: + break; + } + pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument, 0); } diff --git a/test/prism/errors/match_predicate_after_and_with_opreator.txt b/test/prism/errors/match_predicate_after_and_with_opreator.txt new file mode 100644 index 0000000000..5a0c5925ea --- /dev/null +++ b/test/prism/errors/match_predicate_after_and_with_opreator.txt @@ -0,0 +1,3 @@ +1 and 2 in 3 % 4 + ^ unexpected '%', expecting end-of-input + diff --git a/test/prism/errors/match_predicate_after_or_with_opreator.txt b/test/prism/errors/match_predicate_after_or_with_opreator.txt new file mode 100644 index 0000000000..8ea69e4787 --- /dev/null +++ b/test/prism/errors/match_predicate_after_or_with_opreator.txt @@ -0,0 +1,3 @@ +1 or 2 in 3 + 4 + ^ unexpected '+', expecting end-of-input + diff --git a/test/prism/errors/match_predicate_after_rescue_with_opreator.txt b/test/prism/errors/match_predicate_after_rescue_with_opreator.txt new file mode 100644 index 0000000000..b2363a544d --- /dev/null +++ b/test/prism/errors/match_predicate_after_rescue_with_opreator.txt @@ -0,0 +1,3 @@ +1 rescue 2 in 3 << 4 + ^~ unexpected <<, expecting end-of-input + diff --git a/test/prism/errors/match_required_after_and_with_opreator.txt b/test/prism/errors/match_required_after_and_with_opreator.txt new file mode 100644 index 0000000000..eafbc1f12a --- /dev/null +++ b/test/prism/errors/match_required_after_and_with_opreator.txt @@ -0,0 +1,3 @@ +1 and 2 => 3 - 4 + ^ unexpected '-', expecting end-of-input + diff --git a/test/prism/errors/match_required_after_or_with_opreator.txt b/test/prism/errors/match_required_after_or_with_opreator.txt new file mode 100644 index 0000000000..c35f3b66e4 --- /dev/null +++ b/test/prism/errors/match_required_after_or_with_opreator.txt @@ -0,0 +1,3 @@ +1 or 2 => 3 ^ 4 + ^ unexpected '^', expecting end-of-input + diff --git a/test/prism/errors/match_required_after_rescue_with_opreator.txt b/test/prism/errors/match_required_after_rescue_with_opreator.txt new file mode 100644 index 0000000000..903e2ccc8e --- /dev/null +++ b/test/prism/errors/match_required_after_rescue_with_opreator.txt @@ -0,0 +1,3 @@ +1 rescue 2 => 3 ** 4 + ^~ unexpected '**', expecting end-of-input +