public partial class StringTests
{
private const string SoftHyphen = "\u00AD";
+ private const string ZeroWidthJoiner = "\u200D"; // weightless in both ICU and NLS
private static readonly char[] s_whiteSpaceCharacters = { '\u0009', '\u000a', '\u000b', '\u000c', '\u000d', '\u0020', '\u0085', '\u00a0', '\u1680' };
[Theory]
do
{
index = ci.IndexOf(this, oldValue, startIndex, this.Length - startIndex, options, &matchLength);
- if (index >= 0)
+
+ // There's the possibility that 'oldValue' has zero collation weight (empty string equivalent).
+ // If this is the case, we behave as if there are no more substitutions to be made.
+
+ if (index >= 0 && matchLength > 0)
{
// append the unmodified portion of string
result.Append(this.AsSpan(startIndex, index - startIndex));
AssertExtensions.Throws<ArgumentException>("oldValue", () => "abc".Replace("", "def", true, CultureInfo.CurrentCulture));
}
+ [Fact]
+ 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));
+ }
+
+ [Fact]
+ public void Replace_StringComparison_WeightlessOldValue_WithLinguisticComparison_TerminatesReplacement()
+ {
+ Assert.Equal("abc" + ZeroWidthJoiner + "def", ("abc" + ZeroWidthJoiner + "def").Replace(ZeroWidthJoiner, "xyz", StringComparison.CurrentCulture));
+ Assert.Equal("abc" + ZeroWidthJoiner + "def", ("abc" + ZeroWidthJoiner + "def").Replace(ZeroWidthJoiner, "xyz", true, CultureInfo.CurrentCulture));
+ }
+
[Theory]
[InlineData(StringComparison.CurrentCulture - 1)]
[InlineData(StringComparison.OrdinalIgnoreCase + 1)]