From e7fe2846121c5729e9bfb0f3970f97be7edcbc62 Mon Sep 17 00:00:00 2001 From: AccursedGalaxy Date: Fri, 24 Jul 2026 20:14:33 +0200 Subject: [PATCH] pagination: fix panic when the last page link has page=0 lastPage() returned 0 when the links.pages.last URL had a page param that parses to 0, so PaginateResp allocated a zero-length page list and set(1, ...) panicked. A last page below 1 is never valid, so clamp it to 1 and return an empty list instead. Fixes #1888 --- do/pagination.go | 6 +++++- do/pagination_test.go | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/do/pagination.go b/do/pagination.go index 227b8c315..8463865b5 100644 --- a/do/pagination.go +++ b/do/pagination.go @@ -135,5 +135,9 @@ func lastPage(resp *godo.Response) (int, error) { return 0, fmt.Errorf("could not find page param: %v", err) } - return page, err + if page < 1 { + return 1, nil + } + + return page, nil } diff --git a/do/pagination_test.go b/do/pagination_test.go index b7fc3ada2..a6513124f 100644 --- a/do/pagination_test.go +++ b/do/pagination_test.go @@ -90,3 +90,19 @@ func Test_Pagination_lastPage(t *testing.T) { } } } + +func Test_PaginateResp_emptyListWithZeroLastPage(t *testing.T) { + // Regression test for https://github.com/digitalocean/doctl/issues/1888: + // a Last page link whose page param parses to 0 (as with an empty + // collection) made lastPage return 0, so set(1, ...) panicked indexing + // a zero-length page list. lastPage clamps such values to 1. + resp := &godo.Response{Links: &godo.Links{Pages: &godo.Pages{Last: "http://example.com/?page=0"}}} + + gen := func(*godo.ListOptions) ([]any, *godo.Response, error) { + return []any{}, resp, nil + } + + list, err := PaginateResp(gen) + assert.NoError(t, err) + assert.Empty(t, list) +}