Repository navigation
Conversation
…board (CapSoftware#3567) caps/page.tsx and spaces/[spaceId]/page.tsx parsed page and limit via Number(value) || default, allowing negative (-1) and fractional (1.5, 2.5) numbers to reach MySQL OFFSET and LIMIT clauses, causing syntax errors and client-side page crashes. Introduced parsePageParam and parseLimitParam in apps/web/lib/pagination.ts to validate positive integers with safe fallbacks and bounds, reused by parsePublicCollectionPage. Added comprehensive unit tests. Closes CapSoftware#3567
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
| const value = Array.isArray(page) ? page[0] : page; | ||
| const parsed = Number(value); | ||
|
|
||
| if (!Number.isInteger(parsed) || parsed < 1) return defaultValue; |
There was a problem hiding this comment.
parsePageParam accepts enormous pages such as 1e308. With the default limit of 15, (page - 1) * limit becomes Infinity, which both dashboards pass to .offset(). That cannot be a valid MySQL offset, so a crafted URL can still make the dashboard query fail. Bound the page so the calculated offset stays within a safe integer range, and add a test for oversized pages.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/lib/pagination.ts
Line: 8
Comment:
**Large pages still fail**
`parsePageParam` accepts enormous pages such as `1e308`. With the default limit of 15, `(page - 1) * limit` becomes `Infinity`, which both dashboards pass to `.offset()`. That cannot be a valid MySQL offset, so a crafted URL can still make the dashboard query fail. Bound the page so the calculated offset stays within a safe integer range, and add a test for oversized pages.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
|
||
| const page = Number(searchParams.page) || 1; | ||
| const limit = Number(searchParams.limit) || 15; | ||
| const page = parsePageParam(searchParams.page, 1); |
There was a problem hiding this comment.
The server now falls back to page 1 for fractional values, but Caps and SharedCaps still read the raw page with Number(...) || 1. Opening ?page=1.5 shows page 1's videos while marking page 1.5 as current. The next link points to page 2.5, which again loads page 1. Use the same parser in both clients, or pass the parsed page from the server.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/(org)/dashboard/caps/page.tsx
Line: 137
Comment:
**Next repeats the first page**
The server now falls back to page 1 for fractional values, but `Caps` and `SharedCaps` still read the raw page with `Number(...) || 1`. Opening `?page=1.5` shows page 1's videos while marking page 1.5 as current. The next link points to page 2.5, which again loads page 1. Use the same parser in both clients, or pass the parsed page from the server.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Summary
Fixes #3567
Linear: CAP-957
Opening
/dashboard/caps?page=-1,/dashboard/caps?page=1.5, or/dashboard/spaces/[spaceId]?limit=2.5resulted in a client-side exception crash due to invalid MySQLLIMITandOFFSETsyntax.Root Cause
Both
apps/web/app/(org)/dashboard/caps/page.tsxandapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxparsedpageandlimitusingNumber(searchParams.page) || 1andNumber(searchParams.limit) || 15.Negative (
-1) and fractional (1.5,2.5) numbers are truthy, passing through into the query'sOFFSET (page - 1) * limitandLIMIT limitwithout being validated as positive integers.Changes
apps/web/lib/pagination.tsprovidingparsePageParamandparseLimitParamto validate that page and limit inputs are integers ≥ 1, with bounds and default values.parsePublicCollectionPageinapps/web/lib/public-collections-policy.tsto delegate toparsePageParam.Number(...)parsing inCapsPageandSharedCapsPagewithparsePageParamandparseLimitParam.apps/web/__tests__/unit/pagination-params.test.tsverifying missing, empty, zero, negative, fractional, array, and oversized inputs.Test plan
bun test apps/web/__tests__/unit/pagination-params.test.ts(6 pass, 23 assertions)bun test apps/web/__tests__/unit/activity-time-ago.test.ts(3 pass, 13 assertions)bun test apps/web/__tests__/unit/video-thumbnail-duration.test.ts(4 pass, 17 assertions)page=-1orpage=1.5cleanly falls back to page 1 instead of throwing syntax errors in SQL queries.Bound page values before merging so oversized inputs cannot still break dashboard queries.
Findings
Fix with agent prompt
Summary
Adds shared helpers to check dashboard page and limit values.
Reviews (1) · Last reviewed commit: "fix(web): validate page and limit query ..." · Reviewed by Greptile