-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
"foo".AsSpan(0, largeNumber) will throw Specified argument was out of the range of valid values. (Parameter 'start').
Note the indicated parameter name. The issue here is the combination of start/length, and there's nothing you can change start to to make this valid as the issue happens to be in the length argument.
We could consider removing the ExceptionArgument.start, or use a different message that doesn't blame start specifically.
runtime/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs
Lines 191 to 207 in 27604b5
| public static ReadOnlySpan<char> AsSpan(this string? text, int start, int length) | |
| { | |
| if (text == null) | |
| { | |
| if (start != 0 || length != 0) | |
| ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start); | |
| return default; | |
| } | |
| #if TARGET_64BIT | |
| // See comment in Span<T>.Slice for how this works. | |
| if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)text.Length) | |
| ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start); | |
| #else | |
| if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start)) | |
| ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start); | |
| #endif |
We don't report the argument in Slice(int, int) for example
runtime/src/libraries/System.Private.CoreLib/src/System/Span.cs
Lines 398 to 412 in 27604b5
| public Span<T> Slice(int start, int length) | |
| { | |
| #if TARGET_64BIT | |
| // Since start and length are both 32-bit, their sum can be computed across a 64-bit domain | |
| // without loss of fidelity. The cast to uint before the cast to ulong ensures that the | |
| // extension from 32- to 64-bit is zero-extending rather than sign-extending. The end result | |
| // of this is that if either input is negative or if the input sum overflows past Int32.MaxValue, | |
| // that information is captured correctly in the comparison against the backing _length field. | |
| // We don't use this same mechanism in a 32-bit process due to the overhead of 64-bit arithmetic. | |
| if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)_length) | |
| ThrowHelper.ThrowArgumentOutOfRangeException(); | |
| #else | |
| if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) | |
| ThrowHelper.ThrowArgumentOutOfRangeException(); | |
| #endif |