Skip to content

Commit 117c9c6

Browse files
committed
Fix handling of non-mergeable char classes in regex prefix analyzer
1 parent 57c3a85 commit 117c9c6

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,18 @@ public void AddCharClass(RegexCharClass cc)
329329
}
330330
}
331331

332+
/// <summary>Adds a regex char class if the classes are mergeable.</summary>
333+
public bool TryAddCharClass(RegexCharClass cc)
334+
{
335+
if (cc.CanMerge && CanMerge)
336+
{
337+
AddCharClass(cc);
338+
return true;
339+
}
340+
341+
return false;
342+
}
343+
332344
private StringBuilder EnsureCategories() =>
333345
_categories ??= new StringBuilder();
334346

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,11 @@ public static (string CharClass, bool CaseInsensitive)[]? ComputeMultipleCharCla
223223
(classes[classPos++] ??= new RegexCharClass()).AddChar(concatChild.Ch);
224224
break;
225225
case RegexNode.Set:
226-
(classes[classPos++] ??= new RegexCharClass()).AddCharClass(RegexCharClass.Parse(concatChild.Str!));
226+
if (!(classes[classPos++] ??= new RegexCharClass()).TryAddCharClass(RegexCharClass.Parse(concatChild.Str!)))
227+
{
228+
// If the classes can't be merged, give up.
229+
return null;
230+
}
227231
break;
228232
case RegexNode.Multi:
229233
for (int c = 0; c < concatChild.Str!.Length && classPos < classes.Length; c++)

src/libraries/System.Text.RegularExpressions/tests/Regex.Match.Tests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ public static IEnumerable<object[]> Match_Basic_TestData()
284284
yield return new object[] { "(?(cat)|dog)", "oof", RegexOptions.None, 0, 3, false, string.Empty };
285285
yield return new object[] { "(?(a:b))", "a", RegexOptions.None, 0, 1, true, string.Empty };
286286
yield return new object[] { "(?(a:))", "a", RegexOptions.None, 0, 1, true, string.Empty };
287+
yield return new object[] { "[^a-z0-9]etag|[^a-z0-9]digest", "this string has .digest as a substring", RegexOptions.None, 16, 7, true, ".digest" };
287288

288289
// No Negation
289290
yield return new object[] { "[abcd-[abcd]]+", "abcxyzABCXYZ`!@#$%^&*()_-+= \t\n", RegexOptions.None, 0, 30, false, string.Empty };

0 commit comments

Comments
 (0)