Fix missing upper-bound guard in LastIndexOf and FindLastIndex#124161
Fix missing upper-bound guard in LastIndexOf and FindLastIndex#124161ViveliDuCh merged 2 commits intodotnet:mainfrom
Conversation
Add the missing index < Count validation to LastIndexOf and FindLastIndex on ImmutableList<T>.Node. Previously, passing index == Count did not throw ArgumentOutOfRangeException and instead returned an incorrect (off-by-one) result silently. This aligns the behavior with ImmutableArray.
|
Tagging subscribers to this area: @dotnet/area-system-collections |
There was a problem hiding this comment.
Pull request overview
Fixes an off-by-one/validation hole in ImmutableList<T> search APIs by adding missing upper-bound checks for LastIndexOf and FindLastIndex, aligning behavior with ImmutableArray<T> (notably throwing when index/startIndex == Count) and handling the empty-range case consistently.
Changes:
- Add
index/startIndex < Countvalidation toImmutableList<T>.Node.LastIndexOfandImmutableList<T>.Node.FindLastIndex(startIndex, count, match). - Return
-1for the empty-range case (startIndex/index == 0 && count == 0) instead of throwing. - Expand test coverage for single-element lists, multiple matches, and the
index/startIndex == Countfailure mode.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/libraries/System.Collections.Immutable/tests/IndexOfTests.cs | Extends shared LastIndexOf test helper to cover single-element cases and index == Count validation. |
| src/libraries/System.Collections.Immutable/tests/ImmutableListTestBase.cs | Adds FindLastIndex coverage for single/multi-element lists and multiple matches, including startIndex == Count throwing. |
| src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs | Adds targeted regression tests for multiple matches and consistency with ImmutableArray<T> throwing behavior. |
| src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs | Implements the missing upper-bound guards and the empty-range -1 behavior in the underlying node search methods. |
...raries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs
Show resolved
Hide resolved
🤖 Copilot Code Review — PR #124161Holistic AssessmentMotivation: This PR addresses a real bug where Approach: The fix correctly adds the missing upper-bound validation ( Net positive: ✅ This is a net positive — it fixes a documented bug, aligns behavior with Detailed Findings✅ Implementation Matches ImmutableArray PatternThe implementation follows the exact pattern used in
This ensures consistency across the immutable collection types. ✅ FindLastIndex Also Correctly FixedThe ✅ Test Coverage is ComprehensiveThe tests cover:
💡 Minor Suggestion: Consider
|
|
@prozolic Thanks for picking this up and for the thorough fix! The changes to both |
Add the missing index < Count validation to
LastIndexOfandFindLastIndexonImmutableList<T>.Node.cs.Previously, passing index == Count did not throw
ArgumentOutOfRangeExceptionand instead returned an incorrect (off-by-one) result silently. This aligns the behavior with ImmutableArray.Changes:
LastIndexOf: Add upper-bound check to the Requires.Range validation (index >= 0 && index < this.Count)FindLastIndex(int, int, Predicate<T>): Add upper-bound check to the Requires.Range validation (startIndex >= 0 && startIndex < this.Count)#70950