fix: strict input validation on POST /api/goals#469
Conversation
- Wrap req.json() in try/catch — returns 400 on malformed JSON - Validate body is a non-null object before destructuring - title: must be non-empty string, trimmed, max 100 characters - target: must be integer in [1, 10000] — blocks 0, negatives, floats, NaN, overflow - unit: clamped to 30 chars silently - recurrence: unknown values default to 'none' explicitly - All bounds defined as named constants Fixes division-by-zero (target:0 → Infinity% progress bar) and negative target making 0-progress goals show as 100% complete. Closes Priyanshu-byte-coder#454
|
@advikdivekar is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel. A member of the Team first needs to authorize it. |
GSSoC Label Checklist 🏷️@Priyanshu-byte-coder — please apply the appropriate labels before merging: Difficulty (pick one):
Quality (optional):
Validation (required to score):
|
Priyanshu-byte-coder
left a comment
There was a problem hiding this comment.
Merge conflict — rebase on main to resolve. The logic and implementation are correct; once conflict is cleared this can merge immediately.
|
@Priyanshu-byte-coder resolved the merge conflicts |
|
@Priyanshu-byte-coder working on the failed checks, will let you know once done |
Problem
POST /api/goalsaccepted arbitrary values with no bounds checking:target: 0→ division by zero in the frontend progress bar (0 / 0 * 100 = Infinity%)target: -1→ a goal withcurrent: 0displayed as 100% completetarget: 0.5,NaN,999999999→ silently storedtitlehad no length cap — a multi-MB string would be persisted and break layoutFix
src/app/api/goals/route.tsreq.json()wrapped in try/catch → returns400 Invalid JSONon parse failuretitle: must be a non-empty string, trimmed, ≤ 100 characterstarget: must be an integer in[1, 10_000]— rejects0, negatives, floats,NaN, and overflow valuesunit: clamped to 30 characters silentlyrecurrence: unknown values default to"none"explicitlyTest plan
POST /api/goalswithtarget: 0returns400POST /api/goalswithtarget: -5returns400POST /api/goalswithtarget: 0.5returns400POST /api/goalswithtarget: 999999999returns400POST /api/goalswith a 101-character title returns400POST /api/goalswith a whitespace-only title returns400POST /api/goalswith malformed JSON returns400Closes #454