Skip to content

fix: clamp negative Skip n to zero - #21

Merged
tr1v3r merged 1 commit into
masterfrom
fix/skip-negative-hint
Sep 14, 2026
Merged

tr1v3r merged 1 commit into
masterfrom
fix/skip-negative-hint

Conversation

@tr1v3r

@tr1v3r tr1v3r commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Problem

Skip(n) documents "n <= 0 keeps everything" (export.go), and element-wise it does — but the sizeHint arithmetic max(sizeHint-n, 0) treated a negative n as skipping a negative amount, inflating the hint:

stream.SliceOf(1, 2, 3).Skip(-1).Count()   // → 4  (wrong; actual elements: 3)
stream.SliceOf(1, 2, 3).Skip(-1).ToSlice() // → [1 2 3]

Count() short-circuits on the known hint, so it disagreed with the materialized result (audit finding M3 in the audit report / F3 in the core audit). ReduceBy's capacity hint inherits the same skew.

Root cause

No input clamp: the "keeps everything" contract was implemented by the iteration loop (nothing skipped) but not by the hint math.

Fix

Clamp at entry — if n < 0 { n = 0 } — so both the loop and sizeHint arithmetic agree: all elements kept, hint exact, Count() == len(ToSlice()).

Test evidence

New TestOps_SkipNonPositiveKeepsAll covers:

  • Skip(-5)/Skip(-1)/Skip(0) on a known-size stream: Count() and ToSlice() agree (all 3 elements);
  • unknown-hint path (From(seq, -1).Skip(-1)): same agreement;
  • composed Skip(1).Skip(-2): hint arithmetic stays exact (Count == 3 of 4).

go build / go vet clean, go test ./... -race -count=1 all ok, golangci-lint 0 issues. Independent of #18/#19/#20 (base: master).

Skip(n<0) is documented as "n <= 0 keeps everything" (export.go), but
the sizeHint arithmetic max(sizeHint-n, 0) turned a negative n into
sizeHint+|n|: SliceOf(1,2,3).Skip(-1).Count() reported 4 while
ToSlice() held 3 elements, and ReduceBy's capacity hint was skewed
accordingly. Clamp n at entry so all elements are kept and the hint
stays exact. Adds TestOps_SkipNonPositiveKeepsAll. Audit finding M2.
@tr1v3r
tr1v3r force-pushed the fix/skip-negative-hint branch from ea7a68e to 29a3f6d Compare September 14, 2026 02:31
@tr1v3r
tr1v3r merged commit 4c2f076 into master Sep 14, 2026
2 checks passed
@tr1v3r
tr1v3r deleted the fix/skip-negative-hint branch September 14, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant