Thanks to visit codestin.com
Credit goes to github.com

Skip to content

string.AsSpan(int, int) throws a misleading exception #115239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
MihaZupan opened this issue May 2, 2025 · 3 comments · May be fixed by #115275
Open

string.AsSpan(int, int) throws a misleading exception #115239

MihaZupan opened this issue May 2, 2025 · 3 comments · May be fixed by #115275

Comments

@MihaZupan
Copy link
Member

"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.

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

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

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 2, 2025
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label May 2, 2025
@MihaZupan MihaZupan added area-System.Memory and removed untriaged New issue has not been triaged by the area owner needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 2, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

@danmoseley
Copy link
Member

We could consider removing the ExceptionArgument.start, or use a different message that doesn't blame start specifically.

Or in the exception helper figure out which of the parameters is to blame.

@jkotas
Copy link
Member

jkotas commented May 2, 2025

Similar issues #53622 and #90939

the exception helper figure out which of the parameters is to blame.

I expect it to be ambiguous most of the time. I would just delete the argument name from the message.

@MihaZupan MihaZupan linked a pull request May 3, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants