Skip to content

Commit

Permalink
[iOS] [HybridGlobalization] Throw PNSE when methods with matchLength …
Browse files Browse the repository at this point in the history
…are used (dotnet#107390)

* Throw PlatformNotSupportedException for matchLength
  • Loading branch information
mkhamoyan authored and jtschuster committed Sep 17, 2024
1 parent f9402d7 commit 4924fc2
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ private unsafe int IndexOf(ReadOnlySpan<char> source, ReadOnlySpan<char> value,
{
Debug.Assert(matchLengthPtr != null);
*matchLengthPtr = 0;
#if TARGET_BROWSER
#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public static IEnumerable<object[]> IndexOf_TestData()
}

// Inputs where matched length does not equal value string length
if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 0, 23, supportedIgnoreCaseIgnoreNonSpaceOptions, 4, 7 };
yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 0, 21, supportedIgnoreCaseIgnoreNonSpaceOptions, 4, 6 };
Expand Down Expand Up @@ -246,7 +246,7 @@ static void RunSpanIndexOfTest(CompareInfo compareInfo, ReadOnlySpan<char> sourc
valueBoundedMemory.MakeReadonly();

Assert.Equal(expected, compareInfo.IndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options));
if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(expected, compareInfo.IndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength));
Assert.Equal(expectedMatchLength, actualMatchLength);
Expand Down Expand Up @@ -334,7 +334,7 @@ public void IndexOf_Invalid()
AssertExtensions.Throws<ArgumentException>("options", () => s_invariantCompare.IndexOf("Test's", 'b', 0, CompareOptions.StringSort));
AssertExtensions.Throws<ArgumentException>("options", () => s_invariantCompare.IndexOf("Test's", 'c', 0, 2, CompareOptions.StringSort));
AssertExtensions.Throws<ArgumentException>("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.StringSort));
if (PlatformDetection.IsHybridGlobalizationOnBrowser)
if (PlatformDetection.IsHybridGlobalizationOnBrowser || PlatformDetection.IsHybridGlobalizationOnApplePlatform)
{
Assert.Throws<PlatformNotSupportedException>(() => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.StringSort, out _));
Assert.Throws<PlatformNotSupportedException>(() => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.Ordinal | CompareOptions.IgnoreWidth, out _));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static void RunSpanLastIndexOfTest(CompareInfo compareInfo, ReadOnlySpan<char> s
valueBoundedMemory.MakeReadonly();

Assert.Equal(expected, compareInfo.LastIndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options));
if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(expected, compareInfo.LastIndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength));
Assert.Equal(expectedMatchLength, actualMatchLength);
Expand Down Expand Up @@ -348,7 +348,7 @@ public void LastIndexOf_Invalid()
AssertExtensions.Throws<ArgumentException>("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, CompareOptions.StringSort));
AssertExtensions.Throws<ArgumentException>("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, CompareOptions.StringSort));
AssertExtensions.Throws<ArgumentException>("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.StringSort));
if (PlatformDetection.IsHybridGlobalizationOnBrowser)
if (PlatformDetection.IsHybridGlobalizationOnBrowser || PlatformDetection.IsHybridGlobalizationOnApplePlatform)
{
Assert.Throws<PlatformNotSupportedException>(() => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.StringSort, out int matchLength));
Assert.Throws<PlatformNotSupportedException>(() => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.Ordinal | CompareOptions.IgnoreWidth, out int matchLength));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -898,14 +898,17 @@ static void TestCore(CompareInfo compareInfo, string source, string value, int s

Assert.Equal(offsetResult, sourceBoundedSpan.IndexOf(valueBoundedSpan, GetStringComparison(options)));
Assert.Equal(offsetResult, compareInfo.IndexOf(sourceBoundedSpan, valueBoundedSpan, options));
Assert.Equal(offsetResult, compareInfo.IndexOf(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (offsetResult >= 0)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(0, matchLength); // not found
Assert.Equal(offsetResult, compareInfo.IndexOf(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (offsetResult >= 0)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
{
Assert.Equal(0, matchLength); // not found
}
}
}
}
Expand Down Expand Up @@ -958,14 +961,17 @@ static void TestCore(CompareInfo compareInfo, string source, string value, int s

Assert.Equal(result, sourceBoundedSpan.LastIndexOf(valueBoundedSpan, GetStringComparison(options)));
Assert.Equal(result, compareInfo.LastIndexOf(sourceBoundedSpan, valueBoundedSpan, options));
Assert.Equal(result, compareInfo.LastIndexOf(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (result >= 0)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(0, matchLength); // not found
Assert.Equal(result, compareInfo.LastIndexOf(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (result >= 0)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
{
Assert.Equal(0, matchLength); // not found
}
}
}
}
Expand Down Expand Up @@ -993,14 +999,17 @@ public void TestIsPrefix(string source, string value, CompareOptions options, bo

Assert.Equal(result, sourceBoundedSpan.StartsWith(valueBoundedSpan, GetStringComparison(options)));
Assert.Equal(result, compareInfo.IsPrefix(sourceBoundedSpan, valueBoundedSpan, options));
Assert.Equal(result, compareInfo.IsPrefix(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (result)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(0, matchLength); // not found
Assert.Equal(result, compareInfo.IsPrefix(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (result)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
{
Assert.Equal(0, matchLength); // not found
}
}
}
}
Expand Down Expand Up @@ -1028,14 +1037,17 @@ public void TestIsSuffix(string source, string value, CompareOptions options, bo

Assert.Equal(result, sourceBoundedSpan.EndsWith(valueBoundedSpan, GetStringComparison(options)));
Assert.Equal(result, compareInfo.IsSuffix(sourceBoundedSpan, valueBoundedSpan, options));
Assert.Equal(result, compareInfo.IsSuffix(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (result)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(0, matchLength); // not found
Assert.Equal(result, compareInfo.IsSuffix(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength));
if (result)
{
Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons
}
else
{
Assert.Equal(0, matchLength); // not found
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,14 +804,14 @@ public static IEnumerable<object[]> Replace_StringComparison_TestData()
yield return new object[] { "", "\0", "y", StringComparison.InvariantCulture, "" };
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
[MemberData(nameof(Replace_StringComparison_TestData))]
public void Replace_StringComparison_ReturnsExpected(string original, string oldValue, string newValue, StringComparison comparisonType, string expected)
{
Assert.Equal(expected, original.Replace(oldValue, newValue, comparisonType));
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/60568", TestPlatforms.Android | TestPlatforms.LinuxBionic)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95503", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public void Replace_StringComparison_TurkishI()
Expand Down Expand Up @@ -871,7 +871,7 @@ public static IEnumerable<object[]> Replace_StringComparisonCulture_TestData()
}
}

[Theory]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
[MemberData(nameof(Replace_StringComparisonCulture_TestData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95503", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public void Replace_StringComparisonCulture_ReturnsExpected(string original, string oldValue, string newValue, bool ignoreCase, CultureInfo culture, string expected)
Expand All @@ -897,15 +897,15 @@ public void Replace_StringComparison_EmptyOldValue_ThrowsArgumentException()
AssertExtensions.Throws<ArgumentException>("oldValue", () => "abc".Replace("", "def", true, CultureInfo.CurrentCulture));
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
public void Replace_StringComparison_WeightlessOldValue_WithOrdinalComparison_Succeeds()
{
Assert.Equal("abcdef", ("abc" + ZeroWidthJoiner).Replace(ZeroWidthJoiner, "def"));
Assert.Equal("abcdef", ("abc" + ZeroWidthJoiner).Replace(ZeroWidthJoiner, "def", StringComparison.Ordinal));
Assert.Equal("abcdef", ("abc" + ZeroWidthJoiner).Replace(ZeroWidthJoiner, "def", StringComparison.OrdinalIgnoreCase));
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
public void Replace_StringComparison_WeightlessOldValue_WithLinguisticComparison_TerminatesReplacement()
{
Assert.Equal("abc" + ZeroWidthJoiner + "def", ("abc" + ZeroWidthJoiner + "def").Replace(ZeroWidthJoiner, "xyz", StringComparison.CurrentCulture));
Expand Down

0 comments on commit 4924fc2

Please sign in to comment.