runtime: MemoryExtensions ToUpper / ToLower don't properly support overlapping buffers

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 = new char[] { '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.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (15 by maintainers)

Most upvoted comments

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.