You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MemoryExtensions ToUpper / ToLower don't properly support overlapping buffers #28494
Per the devdoc on MemoryExtensions.ToUpper / ToLower and similar methods, these APIs are supposed to behave correctly if the source and destination buffers partially overlap.
/// <remarks>If the source and destinations overlap, this method behaves as if the original values are in/// a temporary location before the destination is overwritten.</remarks>
However, I don't think any shipped version of ToUpper or ToLower ever had this behavior. At least, the most recent version just blasts forward without checking to see if the buffers are overlapped.
Span<char>chars=newchar[]{'a','b','c','d'};((ReadOnlySpan<char>)chars).Slice(0,2).ToUpperInvariant(chars.Slice(1,2));Console.WriteLine(chars.ToString());// prints "aAAd", not "aABd"
We should update the documentation to reflect the actual behavior or change the implementation to satisfy the documented behavior, whichever is appropriate.
Can overlapping be determined reliably? If it can be, it should be part of argument validation.
We should definitely consider it. However, one thing we should measure is potential performance regression that might be introduced due to this check, especially for operations on small payloads. Given that its going through TextInfo anyway, it may not matter all that much. We did recently change the methods being called to statics to avoid the overhead: dotnet/coreclr#17890
owever, one thing we should measure is potential performance regression that might be introduced due to this check, especially for operations on small payloads
This is very cheap check. I am not worried about its cost.
Should throw internal static void ThrowNotSupportedException(ExceptionResource resource) with new ExceptionResource.NotSupported_SpanOverlappedOperation ?
Error message Operation on overlapped buffers not supported?
I would throw ArgumentException (or maybe InvalidOperationException, but probably not NotSupportedException). The message seems fine to me.
Maybe This operation is invalid on overlapping buffers.
Let me know if you are planning to submit a fix by Monday, because we want to get the fix in before 6/26. Otherwise, just give me a heads up and I will try to address this issue myself.
Activity
ahsonkhan commentedon Jan 29, 2019
Hmm, that's strange. These tests would have failed if overlapping spans don't work:
https://github.com/dotnet/corefx/blob/db7daabdb592da062d8a80f27bbad1178c364530/src/Common/tests/Tests/System/StringTests.cs#L5185-L5214
FYI, here is when we added the comment + tests: dotnet/corefx@3131eef (as part of dotnet/corefx#27193)
ahsonkhan commentedon Jan 29, 2019
It prints "aABd" for me (.NET Core 3.0).
ahsonkhan commentedon Feb 14, 2019
It turns out the above example just happens to work on .NET Core 3.0 due to recent changes like dotnet/coreclr#20275 since the input is small.
On .NET Core 2.1, the above example would fail (i.e. print aAAd).
We do not support overlapping spans for ToUpper/ToLower and hence we should change the documentation.
For example, a test like this fails:
GSPP commentedon Feb 15, 2019
Can overlapping be determined reliably? If it can be, it should be part of argument validation.
ektrah commentedon Feb 15, 2019
@GSPP Yes. There is an
Overlapsextension method inMemoryExtensions:https://github.com/dotnet/corefx/blob/f078da3a4ddcb99cbb26b59fb67f59fdfb200548/src/Common/src/CoreLib/System/MemoryExtensions.cs#L1461-L1465
ahsonkhan commentedon Feb 15, 2019
We should definitely consider it. However, one thing we should measure is potential performance regression that might be introduced due to this check, especially for operations on small payloads. Given that its going through
TextInfoanyway, it may not matter all that much. We did recently change the methods being called to statics to avoid the overhead: dotnet/coreclr#17890cc @jkotas, @tarekgh
jkotas commentedon Feb 15, 2019
This is very cheap check. I am not worried about its cost.
MarcoRossignoli commentedon Feb 27, 2019
@ahsonkhan do you mean check and throw exception?
ahsonkhan commentedon Feb 27, 2019
Yes.
ahsonkhan commentedon Jun 15, 2019
@adamsitnik, are you still planning on working on this issue?
adamsitnik commentedon Jun 17, 2019
@ahsonkhan I was hoping to do it when I was flying from Seattle to Europe, but I did not. I have unassigned myself
ahsonkhan commentedon Jun 18, 2019
@GSPP, @ektrah, @MarcoRossignoli, are any of you interested in working on this issue?
MarcoRossignoli commentedon Jun 19, 2019
Some specs methods to fix
Should throw
internal static void ThrowNotSupportedException(ExceptionResource resource)with newExceptionResource.NotSupported_SpanOverlappedOperation?Error message
Operation on overlapped buffers not supported?Tests on corefx
System.Memoryclose to https://github.com/dotnet/corefx/blob/master/src/System.Memory/tests/Memory/IndexAndRange.cs#L38?ahsonkhan commentedon Jun 22, 2019
Yes.
I would throw
ArgumentException(or maybeInvalidOperationException, but probably notNotSupportedException). The message seems fine to me.Maybe
This operation is invalid on overlapping buffers.Most of the ToLower/ToUpper tests live next to the StringTests so that would probably be better.
https://github.com/dotnet/corefx/blob/42ecf717478504fd7cc072f3586c6edd1ba57daa/src/Common/tests/Tests/System/StringTests.cs#L5040-L5053
I would also be OK with them being in a new file next to since they are specifically about spans/overlapping (which isn't relevant in the string case):
https://github.com/dotnet/corefx/blob/master/src/System.Memory/tests/ReadOnlySpan/Overlaps.cs
Let me know if you are planning to submit a fix by Monday, because we want to get the fix in before 6/26. Otherwise, just give me a heads up and I will try to address this issue myself.
Thanks.
MarcoRossignoli commentedon Jun 22, 2019
I'll work to have a fix by monday, if something unexpected will happen I'll tell you asap.
ahsonkhan commentedon Jun 25, 2019
Fixed in dotnet/corefx#38778 / dotnet/corefx#38782