Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit cb37183

Browse files
authored
Fix String.Replace implementation (#11039)
* Fix String.Replace implementation String.Replace was callin ga low level CompareInfo method IndexOfCore which cannot be called in some conditions like when using ordinal ignore case option or when running in invariant mode. The fix is to call a higher level method in CompareInfo which can handle such cases becfore calling the lower level method * fix typo
1 parent a2e17fb commit cb37183

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

src/mscorlib/src/System/Globalization/CompareInfo.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,6 @@ public unsafe virtual int IndexOf(string source, char value, int startIndex, int
752752
return IndexOfCore(source, new string(value, 1), startIndex, count, options, null);
753753
}
754754

755-
756755
public unsafe virtual int IndexOf(string source, string value, int startIndex, int count, CompareOptions options)
757756
{
758757
// Validate inputs
@@ -802,6 +801,53 @@ public unsafe virtual int IndexOf(string source, string value, int startIndex, i
802801
return IndexOfCore(source, value, startIndex, count, options, null);
803802
}
804803

804+
// The following IndexOf overload is mainly used by String.Replace. This overload assumes the parameters are already validated
805+
// and the caller is passing a valid matchLengthPtr pointer.
806+
internal unsafe int IndexOf(string source, string value, int startIndex, int count, CompareOptions options, int* matchLengthPtr)
807+
{
808+
Debug.Assert(source != null);
809+
Debug.Assert(value != null);
810+
Debug.Assert(startIndex >= 0);
811+
Debug.Assert(matchLengthPtr != null);
812+
*matchLengthPtr = 0;
813+
814+
if (source.Length == 0)
815+
{
816+
if (value.Length == 0)
817+
{
818+
return 0;
819+
}
820+
return -1;
821+
}
822+
823+
if (startIndex >= source.Length)
824+
{
825+
return -1;
826+
}
827+
828+
if (options == CompareOptions.OrdinalIgnoreCase)
829+
{
830+
int res = IndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
831+
if (res >= 0)
832+
{
833+
*matchLengthPtr = value.Length;
834+
}
835+
return res;
836+
}
837+
838+
if (_invariantMode)
839+
{
840+
int res = IndexOfOrdinal(source, value, startIndex, count, ignoreCase: (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0);
841+
if (res >= 0)
842+
{
843+
*matchLengthPtr = value.Length;
844+
}
845+
return res;
846+
}
847+
848+
return IndexOfCore(source, value, startIndex, count, options, matchLengthPtr);
849+
}
850+
805851
internal int IndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
806852
{
807853
if (_invariantMode)

src/mscorlib/src/System/String.Manipulation.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ private unsafe String ReplaceCore(string oldValue, string newValue, CultureInfo
10251025
if (oldValue.Length == 0)
10261026
throw new ArgumentException(SR.Argument_StringZeroLength, nameof(oldValue));
10271027

1028-
// If they asked to replace oldValue with a null, replace all occurences
1028+
// If they asked to replace oldValue with a null, replace all occurrences
10291029
// with the empty string.
10301030
if (newValue == null)
10311031
newValue = string.Empty;
@@ -1039,10 +1039,11 @@ private unsafe String ReplaceCore(string oldValue, string newValue, CultureInfo
10391039
int matchLength = 0;
10401040

10411041
bool hasDoneAnyReplacements = false;
1042+
CompareInfo ci = referenceCulture.CompareInfo;
10421043

10431044
do
10441045
{
1045-
index = referenceCulture.CompareInfo.IndexOfCore(this, oldValue, startIndex, m_stringLength - startIndex, options, &matchLength);
1046+
index = ci.IndexOf(this, oldValue, startIndex, m_stringLength - startIndex, options, &matchLength);
10461047
if (index >= 0)
10471048
{
10481049
// append the unmodified portion of string

0 commit comments

Comments
 (0)