What's wrong
The range guard in GetRange is
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex + count, Count);
in Containers/ContiguousCollection.cs (~line 379), Containers/InsertionOrderCollection.cs (~line 197) and Containers/OrderedCollection.cs (~line 357, the line just edited for #59). startIndex + count overflows to a negative number when count is large, so the guard passes.
new ContiguousCollection<int> { 1, 2, 3 }.GetRange(1, int.MaxValue);
// OutOfMemoryException: Array dimensions exceeded supported range
// (the new collection is sized with `count` before Array.Copy runs)
new OrderedCollection<int> { 1, 2, 3 }.GetRange(1, int.MaxValue);
// ArgumentException from List<T>.GetRange instead of the documented ArgumentOutOfRangeException
Reproduced against the current main build.
Why it matters
The method is documented to throw ArgumentOutOfRangeException for an invalid range. Instead, ContiguousCollection attempts a multi-gigabyte allocation and fails with OutOfMemoryException, which callers do not expect and typically do not catch. It is also a cheap way for untrusted paging parameters (offset/limit) to trigger a huge allocation.
Suggested fix
After the two non-negative checks, compare in a form that cannot overflow:
ArgumentOutOfRangeException.ThrowIfGreaterThan(count, Count - startIndex);
This still allows the zero-length range at the end (GetRange(Count, 0)) fixed in #59.
Acceptance criteria
GetRange(1, int.MaxValue) throws ArgumentOutOfRangeException on all three collections.
GetRange(Count, 0) still returns an empty collection.
What's wrong
The range guard in
GetRangeisin
Containers/ContiguousCollection.cs(~line 379),Containers/InsertionOrderCollection.cs(~line 197) andContainers/OrderedCollection.cs(~line 357, the line just edited for #59).startIndex + countoverflows to a negative number whencountis large, so the guard passes.Reproduced against the current
mainbuild.Why it matters
The method is documented to throw
ArgumentOutOfRangeExceptionfor an invalid range. Instead,ContiguousCollectionattempts a multi-gigabyte allocation and fails withOutOfMemoryException, which callers do not expect and typically do not catch. It is also a cheap way for untrusted paging parameters (offset/limit) to trigger a huge allocation.Suggested fix
After the two non-negative checks, compare in a form that cannot overflow:
This still allows the zero-length range at the end (
GetRange(Count, 0)) fixed in #59.Acceptance criteria
GetRange(1, int.MaxValue)throwsArgumentOutOfRangeExceptionon all three collections.GetRange(Count, 0)still returns an empty collection.