Fix NRange.GetOffsetAndLength truncation: cast to nuint instead of uint#124300
Fix NRange.GetOffsetAndLength truncation: cast to nuint instead of uint#124300
Conversation
… tests Co-authored-by: vcsjones <361677+vcsjones@users.noreply.github.com>
Co-authored-by: vcsjones <361677+vcsjones@users.noreply.github.com>
|
Tagging subscribers to this area: @dotnet/area-system-numerics-tensors |
There was a problem hiding this comment.
Pull request overview
Fixes incorrect range validation in System.Buffers.NRange.GetOffsetAndLength on 64-bit platforms by avoiding truncating casts, ensuring out-of-range values above uint.MaxValue are rejected correctly.
Changes:
- Update
GetOffsetAndLengthvalidation logic to cast tonuintinstead ofuintto prevent 64-bit truncation. - Refactor
GetOffsetAndLengthtests from a single[Fact]into multiple[Theory]cases. - Add 64-bit-only test cases covering values above
uint.MaxValue, including regression coverage for the truncation scenario.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/libraries/System.Numerics.Tensors/src/System/Buffers/NRange.cs | Fixes range validation by using nuint casts to avoid 64-bit truncation. |
| src/libraries/System.Numerics.Tensors/tests/NRangeTests.cs | Expands/organizes test coverage and adds 64-bit regression cases for large values. |
🤖 Copilot Code Review (focused on
|
…nt (dotnet#124300) ## Description `NRange.GetOffsetAndLength` casts its `nint` parameters to `uint` for range validation. On 64-bit platforms, this truncates values larger than `uint.MaxValue`, allowing invalid ranges to pass validation silently. ```csharp // Before: truncates upper 32 bits on 64-bit platforms if ((uint)end > (uint)length || (uint)start > (uint)end) // After: correct comparison for all nint values if ((nuint)end > (nuint)length || (nuint)start > (nuint)end) ``` For example, `start = 0x1_0000_0001` and `end = 2` with `length = 0x1_0000_0003`: the `(uint)` cast truncates start to `1`, making `1 > 2` false and incorrectly passing validation. **Note:** Other `(uint)` conversion issues in `NRange` (e.g., `ToString`) are intentionally not addressed here — those are covered by dotnet#124294. ### Tests - Converted existing `GetOffsetAndLengthTest` `[Fact]` to `[Theory]` with `[InlineData]` - Split success and exception cases into separate theory methods - Added `[ConditionalTheory(Is64BitProcess)]` tests exercising values above `uint.MaxValue`, including a case that directly catches the truncation bug <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vcsjones <361677+vcsjones@users.noreply.github.com>
Description
NRange.GetOffsetAndLengthcasts itsnintparameters touintfor range validation. On 64-bit platforms, this truncates values larger thanuint.MaxValue, allowing invalid ranges to pass validation silently.For example,
start = 0x1_0000_0001andend = 2withlength = 0x1_0000_0003: the(uint)cast truncates start to1, making1 > 2false and incorrectly passing validation.Note: Other
(uint)conversion issues inNRange(e.g.,ToString) are intentionally not addressed here — those are covered by #124294.Tests
GetOffsetAndLengthTest[Fact]to[Theory]with[InlineData][ConditionalTheory(Is64BitProcess)]tests exercising values aboveuint.MaxValue, including a case that directly catches the truncation bug💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.