Skip to content

Remove unsafe code from StringParser#125640

Open
EgorBo wants to merge 5 commits intodotnet:mainfrom
EgorBo:remove-unsafe-from-stringparser
Open

Remove unsafe code from StringParser#125640
EgorBo wants to merge 5 commits intodotnet:mainfrom
EgorBo:remove-unsafe-from-stringparser

Conversation

@EgorBo
Copy link
Member

@EgorBo EgorBo commented Mar 17, 2026

Replace pointer-based parsing with safe indexing and for loops in ParseNextInt32, ParseNextInt64, ParseNextUInt32, ParseNextUInt64.

Replace pointer-based parsing with safe indexing and for loops
in ParseNextInt32, ParseNextInt64, ParseNextUInt32, ParseNextUInt64.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 17, 2026 01:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes unsafe pointer-based parsing from System.IO.StringParser numeric parsing helpers by switching to safe string indexing/for loops, with a small consistency fix around empty-component handling.

Changes:

  • Replaced fixed/pointer loops with safe indexed loops in ParseNextInt32/Int64/UInt32/UInt64.
  • Added/standardized empty-component validation (notably for ParseNextUInt64).

EgorBo and others added 2 commits March 17, 2026 02:57
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d add empty-component tests

- Use AsSpan slice in all parse methods so JIT can eliminate bounds checks
- Add Theory test covering empty component -> InvalidDataException for all
  numeric parse methods

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 17, 2026 02:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes unsafe pointer-based parsing from System.IO.StringParser numeric parsing helpers, replacing it with safe ReadOnlySpan<char> indexing and for loops while keeping the same overflow/invalid-data behavior.

Changes:

  • Rewrote ParseNextInt32, ParseNextInt64, ParseNextUInt32, and ParseNextUInt64 to avoid fixed/pointers and instead parse via spans and indexing.
  • Added a new unit test intended to validate that empty components throw InvalidDataException for numeric parsing.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/libraries/Common/src/System/IO/StringParser.cs Replaces pointer-based numeric parsing loops with span/index-based parsing and explicit empty-component checks.
src/libraries/Common/tests/Tests/System/IO/StringParserTests.cs Adds a theory to validate numeric parsers throw InvalidDataException on empty components.

…anch

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@EgorBo
Copy link
Member Author

EgorBo commented Mar 17, 2026

@MihuBot

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes unsafe pointer-based parsing from StringParser’s numeric parsing APIs by switching to ReadOnlySpan<char> indexing/loops, and adds a regression test to ensure empty components throw InvalidDataException.

Changes:

  • Replaced pointer iteration with ReadOnlySpan<char> + for loops in ParseNextInt32/Int64/UInt32/UInt64.
  • Added a new xUnit theory covering empty components for all four numeric parse methods.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/libraries/Common/src/System/IO/StringParser.cs Converts numeric parsing implementations from unsafe pointer-based logic to safe span-based loops.
src/libraries/Common/tests/Tests/System/IO/StringParserTests.cs Adds a theory to validate empty-component behavior for numeric parsers.

@EgorBo EgorBo marked this pull request as ready for review March 17, 2026 14:14
Copilot AI review requested due to automatic review settings March 17, 2026 14:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes unsafe pointer-based parsing from StringParser numeric parsing methods by switching to ReadOnlySpan<char> indexing and for loops.

Changes:

  • Replaced pointer iteration with span indexing in ParseNextInt32 and ParseNextInt64.
  • Replaced pointer iteration with span indexing in ParseNextUInt32 and ParseNextUInt64.
  • Added explicit empty-span validation before parsing.

Comment on lines +141 to +148
int startIndex = _startIndex;
int endIndex = _endIndex;
ReadOnlySpan<char> span = _buffer.AsSpan(startIndex, endIndex - startIndex);

if (span.IsEmpty)
{
ThrowForInvalidData();
}
MoveNextOrFail();
if (_startIndex == _endIndex)

ReadOnlySpan<char> span = _buffer.AsSpan(_startIndex, _endIndex - _startIndex);

/// <summary>Moves to the next component and parses it as an Int64.</summary>
public unsafe long ParseNextInt64()
public long ParseNextInt64()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know why this is its own custom handler and not just reusing the shared number parsing code used by int/long?

Copy link
Member

@stephentoub stephentoub Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this was written, span didn't exist yet, and we didn't want to allocate strings for each component just to be able to parse them. Now that span exists and you can int/long.Parse from them, that should be doable.

@dotnet-policy-service
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants