Skip to content

Commit 7c365ec

Browse files
authored
Prevent IndexOutOfRangeException in RegexInterpreter (#97916)
* Prevent IndexOutOfRangeException in RegexInterpreter This update fixes the IndexOutOfRangeException in RegexInterpreter by enhancing the `TrackPush` and `TrackPush2` methods. The adjustment involves checking the runtrack position before decrementing it, ensuring that it doesn't become negative, which was the root cause of the exception. This prevents potential out-of-range errors when handling large numbers of repetitions in regular expressions. Fix #62094 * Changed to call EnsureStorage() unconditionally. If EnsureStorage() is called unconditionally, the array will be expanded, so the position will never become negative. When the conditions inside EnsureStorage() are true, it might be necessary to expand the array, regardless of the comparison between newpos and codepos. https://github.com/dotnet/runtime/blob/6ebc8bd86dbc780b2a2a7daf3ab6020f9104f09e/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.MultipleMatches.Tests.cs#L461-L469 Before the change, in this test case, EnsureStorage() is not called because newpos == codepos == 6 from the first time until an exception occurs. Fix #62049
1 parent 1e05afc commit 7c365ec

File tree

2 files changed

+9
-19
lines changed

2 files changed

+9
-19
lines changed

src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexInterpreter.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ private void Advance(int i)
5353
private void Goto(int newpos)
5454
{
5555
// When branching backward, ensure storage.
56-
if (newpos < _codepos)
57-
{
58-
EnsureStorage();
59-
}
56+
EnsureStorage();
6057

6158
_codepos = newpos;
6259
SetOperator((RegexOpcode)_code.Codes[newpos]);
@@ -144,10 +141,7 @@ private void Backtrack()
144141
SetOperator((RegexOpcode)(_code.Codes[newpos] | back));
145142

146143
// When branching backward, ensure storage.
147-
if (newpos < _codepos)
148-
{
149-
EnsureStorage();
150-
}
144+
EnsureStorage();
151145

152146
_codepos = newpos;
153147
}

src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.MultipleMatches.Tests.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -454,19 +454,15 @@ public static IEnumerable<object[]> Matches_TestData()
454454
};
455455
}
456456

457-
if (engine != RegexEngine.Interpreter && // these tests currently fail with RegexInterpreter
458-
RuntimeFeature.IsDynamicCodeCompiled) // if dynamic code isn't compiled, RegexOptions.Compiled falls back to the interpreter, for which these tests currently fail
457+
// Fails on .NET Framework: [ActiveIssue("https://github.com/dotnet/runtime/issues/62094")]
458+
yield return new object[]
459459
{
460-
// Fails on interpreter and .NET Framework: [ActiveIssue("https://github.com/dotnet/runtime/issues/62094")]
461-
yield return new object[]
460+
engine, @"(?:){93}", "x", RegexOptions.None, new[]
462461
{
463-
engine, @"(?:){93}", "x", RegexOptions.None, new[]
464-
{
465-
new CaptureData("", 0, 0),
466-
new CaptureData("", 1, 0)
467-
}
468-
};
469-
}
462+
new CaptureData("", 0, 0),
463+
new CaptureData("", 1, 0)
464+
}
465+
};
470466
#endif
471467
}
472468
}

0 commit comments

Comments
 (0)