Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static void Validate_MatchingTimesOut_ThrowsRegexMatchTimeoutException()
public static void Validate_InvalidPattern_ThrowsArgumentException()
{
RegularExpressionAttribute attribute = new RegularExpressionAttribute("foo(?<1bar)");
AssertExtensions.Throws<ArgumentException>(null, () => attribute.Validate("Any", new ValidationContext(new object())));
Assert.ThrowsAny<ArgumentException>(() => attribute.Validate("Any", new ValidationContext(new object())));
}

public class ClassWithValidToString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void Match_fail()
[Fact]
public void IllegalRegex()
{
AssertExtensions.Throws<ArgumentException>(null, () => new RegexStringValidator("[0-9+"));
Assert.ThrowsAny<ArgumentException>(() => new RegexStringValidator("[0-9+"));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/System.Net.WebProxy/tests/WebProxyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public static void WebProxy_InvalidArgs_Throws()
AssertExtensions.Throws<ArgumentNullException>("destination", () => p.GetProxy(null));
AssertExtensions.Throws<ArgumentNullException>("host", () => p.IsBypassed(null));
AssertExtensions.Throws<ArgumentNullException>("c", () => p.BypassList = null);
AssertExtensions.Throws<ArgumentException>(null, () => p.BypassList = new string[] { "*.com" });
Assert.ThrowsAny<ArgumentException>(() => p.BypassList = new string[] { "*.com" });
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ private static void ValidateAndRoundtrip(object obj, TypeSerializableValue[] blo
}
}

[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
public void RegexExceptionSerializable()
{
try
{
new Regex("*"); // parsing "*" - Quantifier {x,y} following nothing.
}
catch (ArgumentException ex)
{
Assert.Equal(ex.GetType().Name, "RegexParseException");
ArgumentException clone = BinaryFormatterHelpers.Clone(ex);
Assert.IsType<ArgumentException>(clone);
}
}

[Fact]
public void ArraySegmentDefaultCtor()
{
Expand Down
6 changes: 3 additions & 3 deletions src/System.Text.RegularExpressions/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@
<value>Malformed \\p{X} character escape.</value>
</data>
<data name="MakeException" xml:space="preserve">
<value>parsing '{0}' - {1}</value>
<value>Invalid pattern '{0}' at offset {1}. {2}</value>
</data>
<data name="MissingControl" xml:space="preserve">
<value>Missing control character.</value>
</data>
<data name="NestedQuantify" xml:space="preserve">
<value>Nested quantifier {0}.</value>
<value>Nested quantifier '{0}'.</value>
</data>
<data name="NoResultOnFailed" xml:space="preserve">
<value>Result cannot be called on a failed Match.</value>
Expand Down Expand Up @@ -176,7 +176,7 @@
<value>Reference to undefined group number {0}.</value>
</data>
<data name="UndefinedNameRef" xml:space="preserve">
<value>Reference to undefined group name {0}.</value>
<value>Reference to undefined group name '{0}'.</value>
</data>
<data name="UndefinedReference" xml:space="preserve">
<value>(?({0}) ) reference to undefined group.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
<Compile Include="System\Text\RegularExpressions\RegexMatchTimeoutException.cs" />
<Compile Include="System\Text\RegularExpressions\RegexNode.cs" />
<Compile Include="System\Text\RegularExpressions\RegexOptions.cs" />
<Compile Include="System\Text\RegularExpressions\RegexParseError.cs" />
<Compile Include="System\Text\RegularExpressions\RegexParseException.cs" />
<Compile Include="System\Text\RegularExpressions\RegexParser.cs" />
<Compile Include="System\Text\RegularExpressions\RegexPrefix.cs" />
<Compile Include="System\Text\RegularExpressions\RegexReplacement.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ public void AddRange(char first, char last)
}
}

public void AddCategoryFromName(string categoryName, bool invert, bool caseInsensitive, string pattern)
public void AddCategoryFromName(string categoryName, bool invert, bool caseInsensitive, string pattern, int currentPos)
{
if (s_definedCategories.TryGetValue(categoryName, out string category) && !categoryName.Equals(s_internalRegexIgnoreCase))
{
Expand All @@ -543,7 +543,7 @@ public void AddCategoryFromName(string categoryName, bool invert, bool caseInsen
_categories.Append(category);
}
else
AddSet(SetFromProperty(categoryName, invert, pattern));
AddSet(SetFromProperty(categoryName, invert, pattern, currentPos));
}

private void AddCategory(string category)
Expand Down Expand Up @@ -669,7 +669,7 @@ public void AddSpace(bool ecma, bool negate)
}
}

public void AddDigit(bool ecma, bool negate, string pattern)
public void AddDigit(bool ecma, bool negate, string pattern, int currentPos)
{
if (ecma)
{
Expand All @@ -679,7 +679,7 @@ public void AddDigit(bool ecma, bool negate, string pattern)
AddSet(ECMADigitSet);
}
else
AddCategoryFromName("Nd", negate, false, pattern);
AddCategoryFromName("Nd", negate, false, pattern, currentPos);
}

public static string ConvertOldStringsToClass(string set, string category)
Expand Down Expand Up @@ -1113,7 +1113,7 @@ private void Canonicalize()
}
}

private static string SetFromProperty(string capname, bool invert, string pattern)
private static string SetFromProperty(string capname, bool invert, string pattern, int currentPos)
{
int min = 0;
int max = s_propTable.Length;
Expand Down Expand Up @@ -1143,7 +1143,9 @@ private static string SetFromProperty(string capname, bool invert, string patter
}
}
}
throw new ArgumentException(SR.Format(SR.MakeException, pattern, SR.Format(SR.UnknownProperty, capname)));

throw new RegexParseException(RegexParseError.UnknownUnicodeProperty, currentPos,
SR.Format(SR.MakeException, pattern, currentPos, SR.Format(SR.UnknownProperty, capname)));
}

#if DEBUG
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace System.Text.RegularExpressions
{
internal enum RegexParseError
{
TooManyAlternates,
IllegalCondition,
IncompleteSlashP,
MalformedSlashP,
UnrecognizedEscape,
UnrecognizedControl,
MissingControl,
TooFewHex,
CaptureGroupOutOfRange,
UndefinedNameRef,
UndefinedBackref,
MalformedNameRef,
IllegalEndEscape,
UnterminatedComment,
UnrecognizedGrouping,
AlternationCantCapture,
AlternationCantHaveComment,
MalformedReference,
UndefinedReference,
InvalidGroupName,
CapnumNotZero,
UnterminatedBracket,
SubtractionMustBeLast,
ReversedCharRange,
BadClassInCharRange,
NotEnoughParentheses,
IllegalRange,
NestedQuantify,
QuantifyAfterNothing,
TooManyParentheses,
UnknownUnicodeProperty
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.Serialization;

namespace System.Text.RegularExpressions
{
[Serializable]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test that breaks when this attribute (or SetType below) is missing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added one.

internal sealed class RegexParseException : ArgumentException
{
private readonly RegexParseError _error;

/// <summary>
/// The error that happened during parsing.
/// </summary>
public RegexParseError Error => _error;

/// <summary>
/// The offset in the supplied pattern.
/// </summary>
public int Offset { get; }

public RegexParseException(RegexParseError error, int offset, string message) : base(message)
{
_error = error;
Offset = offset;
}

public RegexParseException() : base()
{
}

public RegexParseException(string message) : base(message)
{
}

public RegexParseException(string message, Exception inner) : base(message, inner)
{
}

private RegexParseException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
// To maintain serialization support with netfx.
info.SetType(typeof(ArgumentException));
}
}
}
Loading