Reject non-positive lengths in RingBuffer<T> - #53
Merged
Merged
Conversation
RingBuffer<T> passed its length straight to AllocateBuffer with no guard, unlike DelayLine and SpscRingBuffer in the same directory. new RingBuffer<int>(0) succeeded silently and threw IndexOutOfRangeException on the first PushBack; new RingBuffer<int>(-1) did the same while leaving a negative internal Length. The RingBuffer(T value, int length) overload was worse still: a negative length skipped the prefill loop entirely and reported no error at all. Guard in AllocateBuffer so all three constructors, Resize and Resample reject length <= 0 at the call site, matching the sibling buffers. Resize and Resample share the same allocation path and had the identical hole. Fixes #50 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019Z6jU64bBLVThqNZiXkL3c
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #50
Problem
RingBuffer<T>passedlengthstraight toAllocateBufferwith no guard, unlikeDelayLine(int maxDelaySamples)andSpscRingBuffer<T>(int capacity)in the same directory, which both callArgumentOutOfRangeException.ThrowIfNegativeOrZeroup front.new RingBuffer<int>(0)succeeded silently (Capacity0, backing arrayT[0]), then the firstPushBackthrew an unhandledIndexOutOfRangeExceptioninstead of a clearArgumentOutOfRangeExceptionat construction time.new RingBuffer<int>(-1)was likewise accepted — bothNextPower2(0)andNextPower2(-1)evaluate to 0 — and crashed the same way, leavingLengthat-1internally.RingBuffer(T value, int length)was worse: with a negativelengththe prefill loop never ran, so the object was constructed with a negative internalLengthand no error at all.Change
The guard goes in
AllocateBuffer, so all three constructors rejectlength <= 0immediately. That also closes the same hole inResize(int)andResample(int), which share the allocation path and accepted non-positive lengths with identical consequences. Every affected parameter is namedlength, so the thrownParamNameis correct at each public entry point.XML docs on the three constructors,
ResizeandResamplenow carry the matching<exception>element.Tests
Six tests added to
RingBufferTests.cs:Constructor_NonPositiveLength_ThrowsRingBuffer<int>(0),RingBuffer<int>(-1)Constructor_PrefillValue_NonPositiveLength_ThrowsRingBuffer<int>(42, 0 / -1)Constructor_PrefillItems_NonPositiveLength_ThrowsRingBuffer<int>(items, 0 / -1)Resize_NonPositiveLength_ThrowsResize(0),Resize(-1)Resample_NonPositiveLength_ThrowsResample(0),Resample(-1)Constructor_MinimumLength_IsUsablelength == 1still worksThe five validation tests were confirmed to fail without the fix — reverting the guard and re-running gives
failed: 5, succeeded: 358. With the guard restored: 363/363 pass, and no existing test or assertion was altered.The library also builds clean in Release across all five target frameworks (net10.0, net9.0, net8.0, netstandard2.1, netstandard2.0) with 0 warnings —
ThrowIfNegativeOrZeroresolves via the same polyfill the sibling buffers already depend on.🤖 Generated with Claude Code
https://claude.ai/code/session_019Z6jU64bBLVThqNZiXkL3c
Generated by Claude Code