diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d4afac7bd540bf..4ec21e9a9628f7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -126,6 +126,10 @@ https://github.com/dotnet/runtime-assets 6003aa6296ad2bebdf8147de94afbea9b5f16264 + + https://github.com/dotnet/runtime-assets + 6003aa6296ad2bebdf8147de94afbea9b5f16264 + https://github.com/dotnet/runtime-assets 6003aa6296ad2bebdf8147de94afbea9b5f16264 diff --git a/eng/Versions.props b/eng/Versions.props index 6af39feabfeb67..f1274f5d0a9d2d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -127,6 +127,7 @@ 7.0.0-beta.21602.1 7.0.0-beta.21602.1 7.0.0-beta.21602.1 + 7.0.0-beta.21602.1 7.0.0-beta.21602.1 7.0.0-beta.21602.1 diff --git a/src/libraries/System.Text.RegularExpressions/tests/Regex.KnownPattern.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/Regex.KnownPattern.Tests.cs index b53526645705f9..c04207ccb76e9c 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/Regex.KnownPattern.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/Regex.KnownPattern.Tests.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using Xunit; @@ -1405,5 +1407,66 @@ public void TerminationInNonBacktrackingVsBackTracking(RegexOptions options, int // NonBacktracking needs way less than 1s Assert.False(re.Match(input).Success); } + + // + // dotnet/runtime-assets contains a set a regular expressions sourced from + // permissively-licensed packages. Validate Regex behavior with those expressions. + // + + [Theory] + [InlineData(RegexEngine.Interpreter)] + [InlineData(RegexEngine.Compiled)] + public async Task PatternsDataSet_ConstructRegexForAll(RegexEngine engine) + { + foreach (DataSetExpression exp in s_patternsDataSet.Value) + { + await RegexHelpers.GetRegexAsync(engine, exp.Pattern, exp.Options); + } + } + + private static Lazy s_patternsDataSet = new Lazy(() => + { + using Stream json = File.OpenRead("Regex_RealWorldPatterns.json"); + return JsonSerializer.Deserialize(json, new JsonSerializerOptions() { ReadCommentHandling = JsonCommentHandling.Skip }).Distinct().ToArray(); + }); + + private sealed class DataSetExpression : IEquatable + { + public int Count { get; set; } + public RegexOptions Options { get; set; } + public string Pattern { get; set; } + + public bool Equals(DataSetExpression? other) => + other is not null && + other.Pattern == Pattern && + (Options & ~RegexOptions.Compiled) == (other.Options & ~RegexOptions.Compiled); // Compiled doesn't affect semantics, so remove it from equality for our purposes + } + +#if NETCOREAPP + [OuterLoop("Takes many seconds")] + [Fact] + public async Task PatternsDataSet_ConstructRegexForAll_NonBacktracking() + { + foreach (DataSetExpression exp in s_patternsDataSet.Value) + { + try + { + await RegexHelpers.GetRegexAsync(RegexEngine.NonBacktracking, exp.Pattern, exp.Options); + } + catch (Exception e) when (e.Message.Contains(nameof(RegexOptions.NonBacktracking))) { } + } + } + + [OuterLoop("Takes minutes to generate and compile thousands of expressions")] + [Fact] + public void PatternsDataSet_ConstructRegexForAll_SourceGenerated() + { + Parallel.ForEach(s_patternsDataSet.Value.Chunk(50), chunk => + { + RegexHelpers.GetRegexesAsync(RegexEngine.SourceGenerated, + chunk.Select(r => (r.Pattern, (RegexOptions?)r.Options, (TimeSpan?)null)).ToArray()).GetAwaiter().GetResult(); + }); + } +#endif } } diff --git a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj index b9e4b5e2426fb1..9641f9665a175c 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj +++ b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj @@ -38,6 +38,7 @@ + @@ -57,4 +58,7 @@ + + +