From 085456b65e6b45e4008f51fc07f2c084caa17706 Mon Sep 17 00:00:00 2001 From: dev_agent Date: Sun, 11 Oct 2026 01:48:57 -0400 Subject: [PATCH] Count consumed pending states against the bound A consumed state left the map at once but stayed in the queue until it expired, so starting and completing flows grew the queue past the bound. The bound now counts the queue. Co-Authored-By: Claude Opus 5.5 --- internal/auth/auth_test.go | 3 ++- internal/auth/cookie.go | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 9ac6fb9..2d3deab 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -889,11 +889,12 @@ func TestPendingStates(t *testing.T) { t.Error("Consume of an unknown state = true") } - for i := range maxPendingStates { + for i := range maxPendingStates - 1 { if err := p.Add(fmt.Sprint("s", i), now); err != nil { t.Fatalf("Add %d: %v", i, err) } } + // "first" was consumed but has not expired, so it still counts. if err := p.Add("over", now); !errors.Is(err, ErrTooManyPending) { t.Errorf("Add past the bound = %v, want ErrTooManyPending", err) } diff --git a/internal/auth/cookie.go b/internal/auth/cookie.go index df00244..6dffb34 100644 --- a/internal/auth/cookie.go +++ b/internal/auth/cookie.go @@ -200,7 +200,9 @@ func (p *PendingStates) Add(state string, now time.Time) error { expired++ } p.order = p.order[expired:] - if len(p.states) >= maxPendingStates { + // The bound counts every unexpired state, consumed or not: a consumed + // state leaves states at once but order only when it expires. + if len(p.order) >= maxPendingStates { return ErrTooManyPending } expires := now.Add(p.ttl)