fortrangoingonforty/armfortas / d9bb467

Browse files

Fix parser infinite loop on implicit program followed by explicit unit

parse_implicit_program returned without consuming the END PROGRAM
tokens. parse_file re-entered parse_program_unit at the same
position, creating an infinite loop on inputs like:
type :: t / end type / program p / end program

Root cause: parse_unit_body breaks BEFORE the terminator tokens,
leaving them unconsumed. parse_program calls consume_end after
parse_unit_body, but parse_implicit_program did not.

Found by fuzz smoke test with randomized Fortran fragments.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
d9bb467d87ed84683013b141f1d6ab6043fa73ef
Parents
08b0346
Tree
dc73bab

1 changed file

StatusFile+-
M src/parser/unit.rs 9 0
src/parser/unit.rsmodified
@@ -116,6 +116,15 @@ impl<'a> Parser<'a> {
116116
         // No PROGRAM keyword — implicit main program.
117117
         let (uses, imports, implicit, decls, body, ifaces) = self.parse_unit_body(&["program"])?;
118118
 
119
+        // Consume the END [PROGRAM] if present — parse_unit_body breaks
120
+        // *before* consuming the terminator, so we must advance past it
121
+        // or parse_file will re-enter parse_program_unit at the same
122
+        // position forever.
123
+        self.skip_newlines();
124
+        if self.peek() != &TokenKind::Eof {
125
+            let _ = self.consume_end("program");
126
+        }
127
+
119128
         let span = span_from_to(start, self.prev_span());
120129
         Ok(Spanned::new(ProgramUnit::Program {
121130
             name: None, uses, imports, implicit, decls, body, contains: ifaces,