From 365049a7670b49e127e606d3a17704bd384bd6bd Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Tue, 1 Jul 2025 17:10:22 +0100 Subject: [PATCH] Fix crash when using arithmetic expressions in pattern matching When arithmetic expressions like `-1**2` are used in pattern matching contexts, Ruby crashes with "Unexpected node type in pattern matching expression: PM_CALL_NODE". This happens because the Prism parser creates `PM_CALL_NODE` for arithmetic operations, but Ruby's pattern matching compiler doesn't handle call nodes. This fix adds validation to reject `PM_CALL_NODE` in pattern contexts with a proper syntax error. --- src/prism.c | 8 ++++++++ test/prism/errors/pattern_arithmetic_expressions.txt | 3 +++ 2 files changed, 11 insertions(+) create mode 100644 test/prism/errors/pattern_arithmetic_expressions.txt diff --git a/src/prism.c b/src/prism.c index c5f5744f58..4dd519962a 100644 --- a/src/prism.c +++ b/src/prism.c @@ -17393,6 +17393,14 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm // If we found a label, we need to immediately return to the caller. if (pm_symbol_node_label_p(node)) return node; + // Call nodes (arithmetic operations) are not allowed in patterns + if (PM_NODE_TYPE(node) == PM_CALL_NODE) { + pm_parser_err_node(parser, node, diag_id); + pm_missing_node_t *missing_node = pm_missing_node_create(parser, node->location.start, node->location.end); + pm_node_destroy(parser, node); + return (pm_node_t *) missing_node; + } + // Now that we have a primitive, we need to check if it's part of a range. if (accept2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) { pm_token_t operator = parser->previous; diff --git a/test/prism/errors/pattern_arithmetic_expressions.txt b/test/prism/errors/pattern_arithmetic_expressions.txt new file mode 100644 index 0000000000..cfb3650531 --- /dev/null +++ b/test/prism/errors/pattern_arithmetic_expressions.txt @@ -0,0 +1,3 @@ +case 1; in -1**2; end + ^~~~~ expected a pattern expression after the `in` keyword +