Skip to content

Commit 2e43c34

Browse files
authored
Porting roslyn regex tests to corefx (dotnet/corefx#29178)
* Add regex roslyn tests * Offset & serialization in exception, remove internal error in error enum, compile parser tests on netfx * Move match parser tests over to RegexParserTests * Add subexpression parsing * Add test case for SetType in RegexParseException Commit migrated from dotnet/corefx@455f969
1 parent 9152fc2 commit 2e43c34

File tree

14 files changed

+1242
-279
lines changed

14 files changed

+1242
-279
lines changed

src/libraries/System.ComponentModel.Annotations/tests/RegularExpressionAttributeTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public static void Validate_MatchingTimesOut_ThrowsRegexMatchTimeoutException()
8686
public static void Validate_InvalidPattern_ThrowsArgumentException()
8787
{
8888
RegularExpressionAttribute attribute = new RegularExpressionAttribute("foo(?<1bar)");
89-
AssertExtensions.Throws<ArgumentException>(null, () => attribute.Validate("Any", new ValidationContext(new object())));
89+
Assert.ThrowsAny<ArgumentException>(() => attribute.Validate("Any", new ValidationContext(new object())));
9090
}
9191

9292
public class ClassWithValidToString

src/libraries/System.Configuration.ConfigurationManager/tests/Mono/RegexStringValidatorTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void Match_fail()
6767
[Fact]
6868
public void IllegalRegex()
6969
{
70-
AssertExtensions.Throws<ArgumentException>(null, () => new RegexStringValidator("[0-9+"));
70+
Assert.ThrowsAny<ArgumentException>(() => new RegexStringValidator("[0-9+"));
7171
}
7272
}
7373
}

src/libraries/System.Net.WebProxy/tests/WebProxyTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public static void WebProxy_InvalidArgs_Throws()
114114
AssertExtensions.Throws<ArgumentNullException>("destination", () => p.GetProxy(null));
115115
AssertExtensions.Throws<ArgumentNullException>("host", () => p.IsBypassed(null));
116116
AssertExtensions.Throws<ArgumentNullException>("c", () => p.BypassList = null);
117-
AssertExtensions.Throws<ArgumentException>(null, () => p.BypassList = new string[] { "*.com" });
117+
Assert.ThrowsAny<ArgumentException>(() => p.BypassList = new string[] { "*.com" });
118118
}
119119

120120
[Fact]

src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,22 @@ private static void ValidateAndRoundtrip(object obj, TypeSerializableValue[] blo
132132
}
133133
}
134134

135+
[Fact]
136+
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
137+
public void RegexExceptionSerializable()
138+
{
139+
try
140+
{
141+
new Regex("*"); // parsing "*" - Quantifier {x,y} following nothing.
142+
}
143+
catch (ArgumentException ex)
144+
{
145+
Assert.Equal(ex.GetType().Name, "RegexParseException");
146+
ArgumentException clone = BinaryFormatterHelpers.Clone(ex);
147+
Assert.IsType<ArgumentException>(clone);
148+
}
149+
}
150+
135151
[Fact]
136152
public void ArraySegmentDefaultCtor()
137153
{

src/libraries/System.Text.RegularExpressions/src/Resources/Strings.resx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@
125125
<value>Malformed \\p{X} character escape.</value>
126126
</data>
127127
<data name="MakeException" xml:space="preserve">
128-
<value>parsing '{0}' - {1}</value>
128+
<value>Invalid pattern '{0}' at offset {1}. {2}</value>
129129
</data>
130130
<data name="MissingControl" xml:space="preserve">
131131
<value>Missing control character.</value>
132132
</data>
133133
<data name="NestedQuantify" xml:space="preserve">
134-
<value>Nested quantifier {0}.</value>
134+
<value>Nested quantifier '{0}'.</value>
135135
</data>
136136
<data name="NoResultOnFailed" xml:space="preserve">
137137
<value>Result cannot be called on a failed Match.</value>
@@ -176,7 +176,7 @@
176176
<value>Reference to undefined group number {0}.</value>
177177
</data>
178178
<data name="UndefinedNameRef" xml:space="preserve">
179-
<value>Reference to undefined group name {0}.</value>
179+
<value>Reference to undefined group name '{0}'.</value>
180180
</data>
181181
<data name="UndefinedReference" xml:space="preserve">
182182
<value>(?({0}) ) reference to undefined group.</value>

src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
<Compile Include="System\Text\RegularExpressions\RegexMatchTimeoutException.cs" />
3838
<Compile Include="System\Text\RegularExpressions\RegexNode.cs" />
3939
<Compile Include="System\Text\RegularExpressions\RegexOptions.cs" />
40+
<Compile Include="System\Text\RegularExpressions\RegexParseError.cs" />
41+
<Compile Include="System\Text\RegularExpressions\RegexParseException.cs" />
4042
<Compile Include="System\Text\RegularExpressions\RegexParser.cs" />
4143
<Compile Include="System\Text\RegularExpressions\RegexPrefix.cs" />
4244
<Compile Include="System\Text\RegularExpressions\RegexReplacement.cs" />

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ public void AddRange(char first, char last)
526526
}
527527
}
528528

529-
public void AddCategoryFromName(string categoryName, bool invert, bool caseInsensitive, string pattern)
529+
public void AddCategoryFromName(string categoryName, bool invert, bool caseInsensitive, string pattern, int currentPos)
530530
{
531531
if (s_definedCategories.TryGetValue(categoryName, out string category) && !categoryName.Equals(s_internalRegexIgnoreCase))
532532
{
@@ -543,7 +543,7 @@ public void AddCategoryFromName(string categoryName, bool invert, bool caseInsen
543543
_categories.Append(category);
544544
}
545545
else
546-
AddSet(SetFromProperty(categoryName, invert, pattern));
546+
AddSet(SetFromProperty(categoryName, invert, pattern, currentPos));
547547
}
548548

549549
private void AddCategory(string category)
@@ -669,7 +669,7 @@ public void AddSpace(bool ecma, bool negate)
669669
}
670670
}
671671

672-
public void AddDigit(bool ecma, bool negate, string pattern)
672+
public void AddDigit(bool ecma, bool negate, string pattern, int currentPos)
673673
{
674674
if (ecma)
675675
{
@@ -679,7 +679,7 @@ public void AddDigit(bool ecma, bool negate, string pattern)
679679
AddSet(ECMADigitSet);
680680
}
681681
else
682-
AddCategoryFromName("Nd", negate, false, pattern);
682+
AddCategoryFromName("Nd", negate, false, pattern, currentPos);
683683
}
684684

685685
public static string ConvertOldStringsToClass(string set, string category)
@@ -1113,7 +1113,7 @@ private void Canonicalize()
11131113
}
11141114
}
11151115

1116-
private static string SetFromProperty(string capname, bool invert, string pattern)
1116+
private static string SetFromProperty(string capname, bool invert, string pattern, int currentPos)
11171117
{
11181118
int min = 0;
11191119
int max = s_propTable.Length;
@@ -1143,7 +1143,9 @@ private static string SetFromProperty(string capname, bool invert, string patter
11431143
}
11441144
}
11451145
}
1146-
throw new ArgumentException(SR.Format(SR.MakeException, pattern, SR.Format(SR.UnknownProperty, capname)));
1146+
1147+
throw new RegexParseException(RegexParseError.UnknownUnicodeProperty, currentPos,
1148+
SR.Format(SR.MakeException, pattern, currentPos, SR.Format(SR.UnknownProperty, capname)));
11471149
}
11481150

11491151
#if DEBUG
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace System.Text.RegularExpressions
6+
{
7+
internal enum RegexParseError
8+
{
9+
TooManyAlternates,
10+
IllegalCondition,
11+
IncompleteSlashP,
12+
MalformedSlashP,
13+
UnrecognizedEscape,
14+
UnrecognizedControl,
15+
MissingControl,
16+
TooFewHex,
17+
CaptureGroupOutOfRange,
18+
UndefinedNameRef,
19+
UndefinedBackref,
20+
MalformedNameRef,
21+
IllegalEndEscape,
22+
UnterminatedComment,
23+
UnrecognizedGrouping,
24+
AlternationCantCapture,
25+
AlternationCantHaveComment,
26+
MalformedReference,
27+
UndefinedReference,
28+
InvalidGroupName,
29+
CapnumNotZero,
30+
UnterminatedBracket,
31+
SubtractionMustBeLast,
32+
ReversedCharRange,
33+
BadClassInCharRange,
34+
NotEnoughParentheses,
35+
IllegalRange,
36+
NestedQuantify,
37+
QuantifyAfterNothing,
38+
TooManyParentheses,
39+
UnknownUnicodeProperty
40+
}
41+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Runtime.Serialization;
6+
7+
namespace System.Text.RegularExpressions
8+
{
9+
[Serializable]
10+
internal sealed class RegexParseException : ArgumentException
11+
{
12+
private readonly RegexParseError _error;
13+
14+
/// <summary>
15+
/// The error that happened during parsing.
16+
/// </summary>
17+
public RegexParseError Error => _error;
18+
19+
/// <summary>
20+
/// The offset in the supplied pattern.
21+
/// </summary>
22+
public int Offset { get; }
23+
24+
public RegexParseException(RegexParseError error, int offset, string message) : base(message)
25+
{
26+
_error = error;
27+
Offset = offset;
28+
}
29+
30+
public RegexParseException() : base()
31+
{
32+
}
33+
34+
public RegexParseException(string message) : base(message)
35+
{
36+
}
37+
38+
public RegexParseException(string message, Exception inner) : base(message, inner)
39+
{
40+
}
41+
42+
private RegexParseException(SerializationInfo info, StreamingContext context)
43+
: base(info, context)
44+
{
45+
}
46+
47+
public override void GetObjectData(SerializationInfo info, StreamingContext context)
48+
{
49+
base.GetObjectData(info, context);
50+
// To maintain serialization support with netfx.
51+
info.SetType(typeof(ArgumentException));
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)