From b21e1aed2ed5b22b50efc658289a403eeed581df Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 13 Feb 2025 13:58:49 -0500 Subject: [PATCH] [ruby/prism] Fix infinite loop in error recovery When recovering from a depth error that occurs at the end of the file, we need to break out of parsing statements. Fixes [Bug #21114] https://github.com/ruby/prism/commit/a32e268787 --- prism/prism.c | 9 +++++++++ .../block_beginning_with_brace_and_ending_with_end.txt | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/prism/prism.c b/prism/prism.c index 3b23bd3dee..6f8d5b005d 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -13948,6 +13948,15 @@ parse_statements(pm_parser_t *parser, pm_context_t context, uint16_t depth) { if (PM_NODE_TYPE_P(node, PM_MISSING_NODE)) { parser_lex(parser); + // If we are at the end of the file, then we need to stop parsing + // the statements entirely at this point. Mark the parser as + // recovering, as we know that EOF closes the top-level context, and + // then break out of the loop. + if (match1(parser, PM_TOKEN_EOF)) { + parser->recovering = true; + break; + } + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); if (context_terminator(context, &parser->current)) break; } else if (!accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_EOF)) { diff --git a/test/prism/errors/block_beginning_with_brace_and_ending_with_end.txt b/test/prism/errors/block_beginning_with_brace_and_ending_with_end.txt index f0fa964c8a..16af8200ec 100644 --- a/test/prism/errors/block_beginning_with_brace_and_ending_with_end.txt +++ b/test/prism/errors/block_beginning_with_brace_and_ending_with_end.txt @@ -1,6 +1,5 @@ x.each { x end ^~~ unexpected 'end', expecting end-of-input ^~~ unexpected 'end', ignoring it - ^ unexpected end-of-input, assuming it is closing the parent top level context ^ expected a block beginning with `{` to end with `}`