diff --git a/src/app/api/search/torrents/route.test.ts b/src/app/api/search/torrents/route.test.ts index dbb0edd..65ace5c 100644 --- a/src/app/api/search/torrents/route.test.ts +++ b/src/app/api/search/torrents/route.test.ts @@ -67,6 +67,17 @@ describe('Torrent Search API', () => { expect(data.error).toBe('Invalid limit. Must be a number.'); }); + it('should return 400 for partial, fractional, or unsafe integer limits', async () => { + for (const limit of ['10abc', '1.5', '9007199254740992']) { + const request = createRequest({ q: 'test', limit }); + const response = await GET(request); + + expect(response.status).toBe(400); + const data = await response.json(); + expect(data.error).toBe('Invalid limit. Must be a number.'); + } + }); + it('should return 400 if limit exceeds maximum', async () => { const request = createRequest({ q: 'test', limit: '200' }); const response = await GET(request); @@ -94,6 +105,17 @@ describe('Torrent Search API', () => { expect(data.error).toBe('Invalid offset. Must be a number.'); }); + it('should return 400 for partial, fractional, or unsafe integer offsets', async () => { + for (const offset of ['10abc', '1.5', '9007199254740992']) { + const request = createRequest({ q: 'test', offset }); + const response = await GET(request); + + expect(response.status).toBe(400); + const data = await response.json(); + expect(data.error).toBe('Invalid offset. Must be a number.'); + } + }); + it('should return 400 for negative offset', async () => { const request = createRequest({ q: 'test', offset: '-1' }); const response = await GET(request); diff --git a/src/app/api/search/torrents/route.ts b/src/app/api/search/torrents/route.ts index fdbdba8..03af83b 100644 --- a/src/app/api/search/torrents/route.ts +++ b/src/app/api/search/torrents/route.ts @@ -39,6 +39,15 @@ const MAX_LIMIT = 100; */ const DEFAULT_LIMIT = 50; +function parseStrictIntegerParam(value: string | null): number | null { + if (value == null || !/^-?\d+$/.test(value)) { + return null; + } + + const parsed = Number(value); + return Number.isSafeInteger(parsed) ? parsed : null; +} + /** * Extended search result with source */ @@ -125,8 +134,8 @@ export async function GET(request: NextRequest): Promise