summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2025-02-13 13:58:49 -0500
committergit <svn-admin@ruby-lang.org>2025-02-13 19:12:10 +0000
commitb21e1aed2ed5b22b50efc658289a403eeed581df (patch)
treee9b6b606b96082b9f5924cd3b0c1aba8dd8be7f3
parent2b92172894e755362a7a0b74ef3b6a5543a89017 (diff)
[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
-rw-r--r--prism/prism.c9
-rw-r--r--test/prism/errors/block_beginning_with_brace_and_ending_with_end.txt1
2 files changed, 9 insertions, 1 deletions
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 `}`