From df1c5553d21037459a89caec2cb71adc329233e8 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 25 Jan 2019 13:59:23 +0000 Subject: [PATCH 1/5] string.EndsWithUse SequenceEqual not SequenceCompareTo --- .../shared/System/String.Comparison.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/shared/System/String.Comparison.cs b/src/System.Private.CoreLib/shared/System/String.Comparison.cs index 5bae67be0e82..b35d0246a88e 100644 --- a/src/System.Private.CoreLib/shared/System/String.Comparison.cs +++ b/src/System.Private.CoreLib/shared/System/String.Comparison.cs @@ -566,7 +566,12 @@ public bool EndsWith(string value, StringComparison comparisonType) return CompareInfo.Invariant.IsSuffix(this, value, GetCaseCompareOfComparisonCulture(comparisonType)); case StringComparison.Ordinal: - return this.Length < value.Length ? false : (CompareOrdinalHelper(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0); + return this.Length < value.Length ? + false : + SpanHelpers.SequenceEqual( + ref Unsafe.As(ref Unsafe.Add(ref this.GetRawStringData(), this.Length - value.Length)), + ref Unsafe.As(ref value.GetRawStringData()), + ((nuint)value.Length) * 2); case StringComparison.OrdinalIgnoreCase: return this.Length < value.Length ? false : (CompareInfo.CompareOrdinalIgnoreCase(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0); From 3c2da671b9e41d1b82ec66443b7eb418c18326a3 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 25 Jan 2019 15:31:13 +0000 Subject: [PATCH 2/5] Use Span.SequenceEqual --- .../shared/System/String.Comparison.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/System.Private.CoreLib/shared/System/String.Comparison.cs b/src/System.Private.CoreLib/shared/System/String.Comparison.cs index b35d0246a88e..fcba326c9e5a 100644 --- a/src/System.Private.CoreLib/shared/System/String.Comparison.cs +++ b/src/System.Private.CoreLib/shared/System/String.Comparison.cs @@ -566,12 +566,7 @@ public bool EndsWith(string value, StringComparison comparisonType) return CompareInfo.Invariant.IsSuffix(this, value, GetCaseCompareOfComparisonCulture(comparisonType)); case StringComparison.Ordinal: - return this.Length < value.Length ? - false : - SpanHelpers.SequenceEqual( - ref Unsafe.As(ref Unsafe.Add(ref this.GetRawStringData(), this.Length - value.Length)), - ref Unsafe.As(ref value.GetRawStringData()), - ((nuint)value.Length) * 2); + return this.AsSpan(Length - value.Length).SequenceEqual(value); case StringComparison.OrdinalIgnoreCase: return this.Length < value.Length ? false : (CompareInfo.CompareOrdinalIgnoreCase(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0); From b4b37b128d25ef5f101c01891e47f0b9890a7735 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 25 Jan 2019 15:34:58 +0000 Subject: [PATCH 3/5] Check length prior to subtract --- src/System.Private.CoreLib/shared/System/String.Comparison.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/shared/System/String.Comparison.cs b/src/System.Private.CoreLib/shared/System/String.Comparison.cs index fcba326c9e5a..177bb8cf7999 100644 --- a/src/System.Private.CoreLib/shared/System/String.Comparison.cs +++ b/src/System.Private.CoreLib/shared/System/String.Comparison.cs @@ -566,7 +566,7 @@ public bool EndsWith(string value, StringComparison comparisonType) return CompareInfo.Invariant.IsSuffix(this, value, GetCaseCompareOfComparisonCulture(comparisonType)); case StringComparison.Ordinal: - return this.AsSpan(Length - value.Length).SequenceEqual(value); + return this.Length < value.Length ? false : this.AsSpan(Length - value.Length).SequenceEqual(value); case StringComparison.OrdinalIgnoreCase: return this.Length < value.Length ? false : (CompareInfo.CompareOrdinalIgnoreCase(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0); From 06004e080593eb4c3df6b34b2f9ea01864b81295 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 25 Jan 2019 15:41:01 +0000 Subject: [PATCH 4/5] feedback --- src/System.Private.CoreLib/shared/System/String.Comparison.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/shared/System/String.Comparison.cs b/src/System.Private.CoreLib/shared/System/String.Comparison.cs index 177bb8cf7999..7721fa691930 100644 --- a/src/System.Private.CoreLib/shared/System/String.Comparison.cs +++ b/src/System.Private.CoreLib/shared/System/String.Comparison.cs @@ -566,7 +566,8 @@ public bool EndsWith(string value, StringComparison comparisonType) return CompareInfo.Invariant.IsSuffix(this, value, GetCaseCompareOfComparisonCulture(comparisonType)); case StringComparison.Ordinal: - return this.Length < value.Length ? false : this.AsSpan(Length - value.Length).SequenceEqual(value); + int offset = this.Length - value.Length; + return offset >= 0 && this.AsSpan(offset).SequenceEqual(value); case StringComparison.OrdinalIgnoreCase: return this.Length < value.Length ? false : (CompareInfo.CompareOrdinalIgnoreCase(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0); From 04b10d2409d1ae0705ac8c37135d3cdc8bee4ddb Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 25 Jan 2019 16:32:14 +0000 Subject: [PATCH 5/5] Sorta --- src/System.Private.CoreLib/shared/System/String.Comparison.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/shared/System/String.Comparison.cs b/src/System.Private.CoreLib/shared/System/String.Comparison.cs index 7721fa691930..30024cc14567 100644 --- a/src/System.Private.CoreLib/shared/System/String.Comparison.cs +++ b/src/System.Private.CoreLib/shared/System/String.Comparison.cs @@ -567,7 +567,7 @@ public bool EndsWith(string value, StringComparison comparisonType) case StringComparison.Ordinal: int offset = this.Length - value.Length; - return offset >= 0 && this.AsSpan(offset).SequenceEqual(value); + return (uint)offset <= (uint)this.Length && this.AsSpan(offset).SequenceEqual(value); case StringComparison.OrdinalIgnoreCase: return this.Length < value.Length ? false : (CompareInfo.CompareOrdinalIgnoreCase(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0);