carlos / platform Public

fix(provision): clamp negative max in ListRecords instead of panicking

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell c82f69dcb331f10b5093004c338fec247167a873 parent d40839f
2 files changed, +26 −0
  • internal/provision/provision.go +10 −0
  • internal/provision/provision_test.go +16 −0
diff --git a/internal/provision/provision.go b/internal/provision/provision.go
index 788d3333f..bb24da438 100644
--- a/internal/provision/provision.go
+++ b/internal/provision/provision.go
@@ -243,7 +243,17 @@ func GetRecord(ctx context.Context, s release.Store, acct, app, host string) (*R
// extra keys past the cap to compensate, and truncated must not depend on
// which records happen to be malformed today. A malformed or
// path-disagreeing body (GetRecord's own checks) is skipped, not fatal.
+//
+// A negative max is clamped to 0 rather than treated as "no cap" (a caller
+// passing an unvalidated int — a console handler's query param, most
+// likely — must degrade safely, not panic on the slice below or list
+// everything by accident). max=0 lists nothing but still reports
+// truncated when any keys exist, the same "cap decided on key count" rule
+// applied at its floor.
func ListRecords(ctx context.Context, s release.Store, acct, app string, max int) (recs []Record, truncated bool, err error) {
+ if max < 0 {
+ max = 0
+ }
prefix := RecordsPrefix(acct, app)
keys, err := s.List(ctx, prefix)
if err != nil {
diff --git a/internal/provision/provision_test.go b/internal/provision/provision_test.go
index 32b62167e..902b1abd9 100644
--- a/internal/provision/provision_test.go
+++ b/internal/provision/provision_test.go
@@ -252,6 +252,22 @@ func TestListRecords(t *testing.T) {
if len(recs) != 3 {
t.Fatalf("ListRecords with a malformed body: got %d records, want 3 (malformed skipped)", len(recs))
}
+
+ // max=0 and a negative max must both degrade to "list nothing", never
+ // panic on the slice bound — a console handler hands this an
+ // unvalidated int.
+ for _, max := range []int{0, -1} {
+ recs, truncated, err := ListRecords(ctx, s, "bad", "tito", max)
+ if err != nil {
+ t.Fatalf("ListRecords with max=%d: %v", max, err)
+ }
+ if len(recs) != 0 {
+ t.Errorf("ListRecords with max=%d: got %d records, want 0", max, len(recs))
+ }
+ if !truncated {
+ t.Errorf("ListRecords with max=%d: truncated = false, want true (keys exist)", max)
+ }
+ }
}
func TestGetRecord(t *testing.T) {