-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix various LastIndexOf bugs when dealing with zero-length target substrings #34616
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3379,7 +3379,6 @@ public static void IndexOfSequenceLengthOneValue_Char() | |
| Assert.Equal(2, index); | ||
| Assert.Equal(index, s1.IndexOf(s2, StringComparison.Ordinal)); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.IndexOf(value); | ||
|
|
@@ -3396,7 +3395,6 @@ public static void IndexOfSequenceLengthOneValueAtVeryEnd_Char() | |
| Assert.Equal(5, index); | ||
| Assert.Equal(index, s1.IndexOf(s2, StringComparison.Ordinal)); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.IndexOf(value); | ||
|
|
@@ -3413,7 +3411,6 @@ public static void IndexOfSequenceLengthOneValueJustPasttVeryEnd_Char() | |
| Assert.Equal(-1, index); | ||
| Assert.Equal(index, s1.IndexOf(s2, StringComparison.Ordinal)); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.IndexOf(value); | ||
|
|
@@ -3887,18 +3884,23 @@ public static void LastIndexOf_AllSubstrings(string s, string value, int startIn | |
|
|
||
| if (value.Length == 0) | ||
| { | ||
| int expectedIndex = s.Length > 0 ? s.Length - 1 : 0; | ||
| int expectedStartIndex = startIndex == s.Length ? startIndex - 1 : startIndex; | ||
| int expectedStartIndex = startIndex; | ||
| if (s.Length == 0 && (startIndex == -1 || startIndex == 0)) | ||
| expectedStartIndex = (value.Length == 0) ? 0 : -1; | ||
| Assert.Equal(expectedIndex, s.LastIndexOf(value, comparison)); | ||
| expectedStartIndex = 0; // empty string occurs at beginning of search space | ||
| if (s.Length > 0 && startIndex < s.Length) | ||
| expectedStartIndex = startIndex + 1; // empty string occurs just after the last char included in the search space | ||
|
|
||
| Assert.Equal(s.Length, s.LastIndexOf(value, comparison)); | ||
| Assert.Equal(expectedStartIndex, s.LastIndexOf(value, startIndex, comparison)); | ||
| Assert.Equal(expectedIndex, s.AsSpan().LastIndexOf(value.AsSpan(), comparison)); | ||
| Assert.Equal(s.Length, s.AsSpan().LastIndexOf(value.AsSpan(), comparison)); | ||
| return; | ||
| } | ||
|
|
||
| if (s.Length == 0) | ||
| { | ||
| // unit test shouldn't have passed a weightless string to this routine | ||
| Assert.NotEqual(value, string.Empty, StringComparer.FromComparison(comparison)); | ||
|
|
||
| Assert.Equal(-1, s.LastIndexOf(value, comparison)); | ||
| Assert.Equal(-1, s.LastIndexOf(value, startIndex, comparison)); | ||
| Assert.Equal(-1, s.AsSpan().LastIndexOf(value.AsSpan(), comparison)); | ||
|
|
@@ -4068,8 +4070,8 @@ public static void LastIndexOf_TurkishI_EnglishUSCulture() | |
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not related to your changes: IMHO this test (
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, it's a bit of a bear. Do you have recommendations for how it might naturally be split?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that the two |
||
|
|
||
| [Theory] | ||
| [InlineData("foo", 2)] | ||
| [InlineData("hello", 4)] | ||
| [InlineData("foo", 3)] | ||
| [InlineData("hello", 5)] | ||
| [InlineData("", 0)] | ||
| public static void LastIndexOf_EmptyString(string s, int expected) | ||
| { | ||
|
|
@@ -4325,13 +4327,13 @@ public static void LastIndexOfSequenceZeroLengthValue_Char() | |
| string s1 = "0172377457778667789"; | ||
| string s2 = string.Empty; | ||
| int index = s1.LastIndexOf(s2); | ||
| Assert.Equal(s1.Length - 1, index); | ||
| Assert.Equal(s1.Length, index); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| // A zero-length value is always "found" at the end of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.LastIndexOf(value); | ||
| Assert.Equal(0, index); | ||
| Assert.Equal(span.Length, index); | ||
| } | ||
|
|
||
| [Fact] | ||
|
|
@@ -4356,7 +4358,6 @@ public static void LastIndexOfSequenceLengthOneValue_Char() | |
| int index = s1.LastIndexOf(s2); | ||
| Assert.Equal(2, index); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.LastIndexOf(value); | ||
|
|
@@ -4371,7 +4372,6 @@ public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_Char() | |
| int index = s1.LastIndexOf(s2); | ||
| Assert.Equal(5, index); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.LastIndexOf(value); | ||
|
|
@@ -4386,7 +4386,6 @@ public static void LastIndexOfSequenceLengthOneValueMultipleTimes_Char() | |
| int index = s1.LastIndexOf(s2); | ||
| Assert.Equal(5, index); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.LastIndexOf(value); | ||
|
|
@@ -4401,7 +4400,6 @@ public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_Char() | |
| int index = s1.LastIndexOf(s2); | ||
| Assert.Equal(-1, index); | ||
|
|
||
| // A zero-length value is always "found" at the start of the span. | ||
| ReadOnlySpan<char> span = s1.AsSpan(); | ||
| ReadOnlySpan<char> value = s2.AsSpan(); | ||
| index = span.LastIndexOf(value); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.