From a06eb9f88e674f6aa9fba5b69ad600293b7acf87 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Sun, 23 Jun 2019 17:30:58 +0200 Subject: [PATCH] MemoryExtensions ToUpper / ToLower throws for overlapping buffer (#25327) --- src/System.Private.CoreLib/Resources/Strings.resx | 5 ++++- .../shared/System/MemoryExtensions.Fast.cs | 26 +++++++++++++++------- tests/CoreFX/CoreFX.issues.rsp | 6 +++++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/System.Private.CoreLib/Resources/Strings.resx b/src/System.Private.CoreLib/Resources/Strings.resx index 3bd8d5a..653c1d3 100644 --- a/src/System.Private.CoreLib/Resources/Strings.resx +++ b/src/System.Private.CoreLib/Resources/Strings.resx @@ -2956,6 +2956,9 @@ Serialization of global methods (including implicit serialization via the use of asynchronous delegates) is not supported. + + This operation is invalid on overlapping buffers. + Invoking default method with named arguments is not supported. @@ -3766,4 +3769,4 @@ Type '{0}' has more than one COM unregistration function. - \ No newline at end of file + diff --git a/src/System.Private.CoreLib/shared/System/MemoryExtensions.Fast.cs b/src/System.Private.CoreLib/shared/System/MemoryExtensions.Fast.cs index 33617b4..801c87f 100644 --- a/src/System.Private.CoreLib/shared/System/MemoryExtensions.Fast.cs +++ b/src/System.Private.CoreLib/shared/System/MemoryExtensions.Fast.cs @@ -219,11 +219,14 @@ namespace System /// The source span. /// The destination span which contains the transformed characters. /// An object that supplies culture-specific casing rules. - /// If the source and destinations overlap, this method behaves as if the original values are in - /// a temporary location before the destination is overwritten. If is null, will be used. + /// If is null, will be used. /// The number of characters written into the destination span. If the destination is too small, returns -1. + /// The source and destination buffers overlap. public static int ToLower(this ReadOnlySpan source, Span destination, CultureInfo? culture) { + if (source.Overlaps(destination)) + throw new InvalidOperationException(SR.InvalidOperation_SpanOverlappedOperation); + if (culture == null) culture = CultureInfo.CurrentCulture; @@ -244,11 +247,13 @@ namespace System /// /// The source span. /// The destination span which contains the transformed characters. - /// If the source and destinations overlap, this method behaves as if the original values are in - /// a temporary location before the destination is overwritten. /// The number of characters written into the destination span. If the destination is too small, returns -1. + /// The source and destination buffers overlap. public static int ToLowerInvariant(this ReadOnlySpan source, Span destination) { + if (source.Overlaps(destination)) + throw new InvalidOperationException(SR.InvalidOperation_SpanOverlappedOperation); + // Assuming that changing case does not affect length if (destination.Length < source.Length) return -1; @@ -267,11 +272,14 @@ namespace System /// The source span. /// The destination span which contains the transformed characters. /// An object that supplies culture-specific casing rules. - /// If the source and destinations overlap, this method behaves as if the original values are in - /// a temporary location before the destination is overwritten. If is null, will be used. + /// If is null, will be used. /// The number of characters written into the destination span. If the destination is too small, returns -1. + /// The source and destination buffers overlap. public static int ToUpper(this ReadOnlySpan source, Span destination, CultureInfo? culture) { + if (source.Overlaps(destination)) + throw new InvalidOperationException(SR.InvalidOperation_SpanOverlappedOperation); + if (culture == null) culture = CultureInfo.CurrentCulture; @@ -292,11 +300,13 @@ namespace System /// /// The source span. /// The destination span which contains the transformed characters. - /// If the source and destinations overlap, this method behaves as if the original values are in - /// a temporary location before the destination is overwritten. /// The number of characters written into the destination span. If the destination is too small, returns -1. + /// The source and destination buffers overlap. public static int ToUpperInvariant(this ReadOnlySpan source, Span destination) { + if (source.Overlaps(destination)) + throw new InvalidOperationException(SR.InvalidOperation_SpanOverlappedOperation); + // Assuming that changing case does not affect length if (destination.Length < source.Length) return -1; diff --git a/tests/CoreFX/CoreFX.issues.rsp b/tests/CoreFX/CoreFX.issues.rsp index e34bcd0..d39d214 100644 --- a/tests/CoreFX/CoreFX.issues.rsp +++ b/tests/CoreFX/CoreFX.issues.rsp @@ -131,3 +131,9 @@ -nomethod System.Diagnostics.Tests.StackTraceTests.Ctor_Exception_LargeSkipFrames_FNeedFileInfo -nomethod System.Diagnostics.Tests.StackTraceTests.Ctor_LargeSkipFrames_GetFramesReturnsNull -nomethod System.Diagnostics.Tests.StackTraceTests.Ctor_LargeSkipFramesFNeedFileInfo_GetFramesReturnsNull + +# requires corefx test updates +-nomethod System.Tests.StringTests.SameSpanToLower +-nomethod System.Tests.StringTests.ToLowerOverlapping +-nomethod System.Tests.StringTests.SameSpanToUpper +-nomethod System.Tests.StringTests.ToUpperOverlapping -- 2.7.4