From fd3c7036db1315ea4c302003288d8aca5bc0e431 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 23 Sep 2026 02:08:36 +0500 Subject: [PATCH] parsers: limit char-class repetition scanning to max Limit the input span before scanning repeated character classes. Previously the entire matching prefix was scanned before the count was clamped to max, so even a single repetition could scan the whole input. --- src/Ramstack.Parsing/Parser.Repeat.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Ramstack.Parsing/Parser.Repeat.cs b/src/Ramstack.Parsing/Parser.Repeat.cs index df64bcb..6e177c1 100644 --- a/src/Ramstack.Parsing/Parser.Repeat.cs +++ b/src/Ramstack.Parsing/Parser.Repeat.cs @@ -448,6 +448,11 @@ public override bool TryParse(ref ParseContext context, [NotNullWhen(true)] out var s = context.Remaining; var count = 0; + // Limit the span before scanning + var length = Math.Min(s.Length, _max); + if ((uint)length <= (uint)s.Length) + s = s.Slice(0, length); + while (s.Length != 0) { var index = _searcher.IndexOfAnyExcept(s); @@ -490,7 +495,6 @@ public override bool TryParse(ref ParseContext context, [NotNullWhen(true)] out if (count < _max) context.ReportExpected(context.Position + count, Name); - count = Math.Min(count, _max); context.Advance(count); value = ListFactory.CreateList(context.MatchedSegment); @@ -541,6 +545,11 @@ public override bool TryParse(ref ParseContext context, out Unit value) var s = context.Remaining; var count = 0; + // Limit the span before scanning + var length = Math.Min(s.Length, _max); + if ((uint)length <= (uint)s.Length) + s = s.Slice(0, length); + while (s.Length != 0) { var index = _searcher.IndexOfAnyExcept(s); @@ -582,7 +591,6 @@ public override bool TryParse(ref ParseContext context, out Unit value) if (count < _max) context.ReportExpected(context.Position + count, Name); - count = Math.Min(count, _max); context.Advance(count); } else