From f50d6d22bdf6d545ee50f74b3a1d4d54f9584259 Mon Sep 17 00:00:00 2001 From: GitHubProUser67 <127040195+GitHubProUser67@users.noreply.github.com> Date: Wed, 18 Feb 2026 18:17:09 +0100 Subject: [PATCH] Fixes a StackOverflow issue with the Lexer system. When doing a lua script with a whole lot of comments starting with "--", it will throw a StackOverflow assertion due to excessive amount of MoveNext calls. This commit fixes that bug by manually doing recursive jobs. --- src/Lua/CodeAnalysis/Syntax/Lexer.cs | 38 ++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/Lua/CodeAnalysis/Syntax/Lexer.cs b/src/Lua/CodeAnalysis/Syntax/Lexer.cs index 322e7c01..5faf57c7 100644 --- a/src/Lua/CodeAnalysis/Syntax/Lexer.cs +++ b/src/Lua/CodeAnalysis/Syntax/Lexer.cs @@ -79,6 +79,11 @@ public bool MoveNext() { case ' ': case '\t': + while (offset < Source.Length && (Source.Span[offset] == ' ' || Source.Span[offset] == '\t')) + { + Advance(1); + } + return MoveNext(); case '\n': current = SyntaxToken.EndOfLine(position); @@ -110,16 +115,16 @@ public bool MoveNext() current = SyntaxToken.Addition(position); return true; case '-': - // comment - if (c2 == '-') + // handle comments iteratively + while (offset < span.Length && c2 == '-') { var pos = position; - Advance(1); + Advance(1); // consume first '-' // block comment - if (span.Length > offset + 1 && span[offset] is '[' && span[offset + 1] is '[' or '=') + if (span.Length > offset + 1 && span[offset] == '[' && (span[offset + 1] == '[' || span[offset + 1] == '=')) { - Advance(1); + Advance(1); // consume second '-' var (_, _, isTerminated) = ReadUntilLongBracketEnd(ref span); if (!isTerminated) { @@ -131,13 +136,24 @@ public bool MoveNext() ReadUntilEOL(ref span, ref offset, out _); } - return MoveNext(); - } - else - { - current = SyntaxToken.Subtraction(position); - return true; + // prepare for next iteration + if (offset < span.Length) + { + c2 = (offset + 1 < span.Length) ? span[offset + 1] : char.MinValue; + if (span[offset] != '-') break; // next char is not a comment, exit loop + } + else + { + break; + } } + + // after skipping comments, if we reached end, return false + if (offset >= span.Length) + return false; + + current = SyntaxToken.Subtraction(position); // if single '-' remains + return true; case '*': current = SyntaxToken.Multiplication(position); return true;