Skip to content

fix(api): bound pagination integers and allocations - #173

Merged
vincentkoc merged 1 commit into
mainfrom
fix/clickclack-pagination-bounds
Aug 27, 2026
Merged

fix(api): bound pagination integers and allocations#173
vincentkoc merged 1 commit into
mainfrom
fix/clickclack-pagination-bounds

Conversation

@vincentkoc

@vincentkoc vincentkoc commented Aug 21, 2026

Copy link
Copy Markdown
Member

Problem

CodeQL alerts 3-7 identify one pagination-boundary defect across the API and both stores:

  • request limits were parsed with architecture-sized strconv.Atoi, then reached PostgreSQL int32 query parameters;
  • page builders expressed result capacity in terms of the request limit instead of the rows actually returned.

Why

The HTTP boundary now parses pagination integers as signed 32-bit values before converting them to Go int. Existing store normalization remains the canonical behavior owner: missing and zero values retain their documented defaults, negative values retain their existing rejection/default behavior, and oversized but representable values are still clamped to each endpoint's public maximum.

PostgreSQL and SQLite member/search page builders now allocate directly from len(rows) or len(entries). This preserves backend parity and prevents request-controlled allocation expressions without changing returned pages.

No public API, configuration, schema, SQL, generated code, or dependency surface changed.

User impact

Out-of-range pagination integers are rejected or fall back before database-width conversions. Valid requests, endpoint defaults, clamps, cursors, and page shapes are unchanged.

Evidence

Pre-fix regression:

go test ./apps/api/internal/httpapi -run 'Test(QueryHelpersParseValues|PaginationLimitParsersUseDatabaseWidth)$' -count=1

queryInt accepted 2147483648, -2147483649, and 9223372036854775807 on 64-bit Go.
The strict search/member parsers accepted 2147483648 and 9223372036854775807.

Post-fix:

go test ./apps/api/internal/httpapi -run 'Test(QueryHelpersParseValues|PaginationLimitParsersUseDatabaseWidth)$' -count=1
go test ./apps/api/internal/httpapi -count=1
go test ./apps/api/internal/store/... -count=1
go test ./... -count=1
CGO_ENABLED=0 GOOS=linux GOARCH=386 go test -c ./apps/api/internal/httpapi

All passed with Go 1.26.6. The final command produced a statically linked 32-bit Intel 80386 test binary.

Boundary coverage includes missing/default, negative, zero, positive, MaxInt32, MaxInt32+1, below MinInt32, and MaxInt64. Existing store tests cover endpoint normalization and PostgreSQL/SQLite parity. No allocation-count assertion was added: the regression is the security boundary, while exact-head CodeQL independently verifies that request-sized allocation flows are gone.

High-reasoning gpt-5.6-sol autoreview reported one proposed MaxInt32-1 cap. Source tracing disproved it: search and member requests normalize to 100 and 200 before their sentinel-row limit + 1, while every queryInt consumer clamps before SQL conversion or sentinel arithmetic. MaxInt32 is therefore safe at ingress and never reaches backend addition.

LOC split:

production: +9/-9 (net 0)
tests:      +60/-3
generated:  0/0

Crabbox clean-machine proof passed on exact head 78931c4:

Exact-head GitHub proof on 78931c48949f8de468b7b476f1ed64fff972b6a2:

  • 12 required/applicable checks passed with zero failures or pending jobs;
  • CodeQL Go analysis 1679826001 on refs/pull/173/head reported zero results;
  • ClawSweeper revision 8 rated the patch A/A/A, marked it correct and security-cleared, reported no findings, and listed no rank-up moves: https://github.com/openclaw/clawsweeper/actions/runs/33048031433

ClawSweeper requested explicit owner acceptance for changing strict search/member overflow from downstream clamping to an ingress error. @vincentkoc is an active openclaw-secops maintainer and explicitly accepted the signed-32-bit ingress boundary for this campaign.

Scope and credit

This updates the existing campaign-owned PR and branch created by @vincentkoc. No external contributor commit was copied. #169 is unrelated web cursor work and remains untouched.

@clawsweeper

clawsweeper Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@vincentkoc
vincentkoc force-pushed the fix/clickclack-pagination-bounds branch from 6932143 to 37ce1eb Compare August 21, 2026 13:16
@vincentkoc

Copy link
Copy Markdown
Member Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🦞👀
Exact review queued.

Re-review progress:

@vincentkoc

Copy link
Copy Markdown
Member Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@vincentkoc
vincentkoc force-pushed the fix/clickclack-pagination-bounds branch from 37ce1eb to 78931c4 Compare August 27, 2026 06:55
@vincentkoc

Copy link
Copy Markdown
Member Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper

clawsweeper Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(api): reject overflowing pagination limits This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@vincentkoc vincentkoc changed the title fix(api): reject overflowing pagination limits fix(api): bound pagination integers and allocations Aug 27, 2026
@vincentkoc
vincentkoc marked this pull request as ready for review August 27, 2026 07:07
@vincentkoc
vincentkoc requested a review from a team as a code owner August 27, 2026 07:07
@clawsweeper

clawsweeper Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@vincentkoc
vincentkoc merged commit 5c664e0 into main Aug 27, 2026
16 checks passed
@vincentkoc
vincentkoc deleted the fix/clickclack-pagination-bounds branch August 27, 2026 07:08
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