[object Object]

← back to Apartmentwallpaper

fix(api): clamp /api/products limit to >=1 so hostile ?limit=-5/0 can't break pagination math

01d22775b0de60d26387d991fb3b355bc48a8146 · 2026-06-01 12:11:56 -0700 · SteveStudio2

parseInt(limit)||24 capped the ceiling at 60 but had no floor, so a negative
or zero limit poisoned Math.ceil(total/lim) and the slice() bounds. Floor at 1.
DTD verdict B (Claude+Codex unanimous): clamp limit now, defer the deliberate
/api/facets 3x-filterProducts (kept for filtered-count correctness).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 01d22775b0de60d26387d991fb3b355bc48a8146
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Mon Jun 1 12:11:56 2026 -0700

    fix(api): clamp /api/products limit to >=1 so hostile ?limit=-5/0 can't break pagination math
    
    parseInt(limit)||24 capped the ceiling at 60 but had no floor, so a negative
    or zero limit poisoned Math.ceil(total/lim) and the slice() bounds. Floor at 1.
    DTD verdict B (Claude+Codex unanimous): clamp limit now, defer the deliberate
    /api/facets 3x-filterProducts (kept for filtered-count correctness).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 server.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server.js b/server.js
index 070722e..93c9b1f 100644
--- a/server.js
+++ b/server.js
@@ -173,7 +173,7 @@ app.get('/api/products', (req, res) => {
   list = sortProducts(list, sort);
   const total = list.length;
   const pageNum = Math.max(1, parseInt(page) || 1);
-  const lim = Math.min(60, parseInt(limit) || 24);
+  const lim = Math.max(1, Math.min(60, parseInt(limit, 10) || 24));
   const start = (pageNum - 1) * lim;
   res.json({ total, page: pageNum, limit: lim, pages: Math.ceil(total / lim), items: list.slice(start, start + lim) });
 });

← c86de10 add afternic unlock/repoint script + passing unit tests (8/8  ·  back to Apartmentwallpaper  ·  fix(theme2): sticky data-theme-preview flag so Theme 1 isn't 0ac44de →