From fe74d4303ce264b6060eb099827e53ecaefdcbc5 Mon Sep 17 00:00:00 2001 From: Saumya Tripathi Date: Sat, 23 May 2026 23:51:07 +0530 Subject: [PATCH 1/2] fix: harden date parsing to reject unrealistic years and invalid strings #107 --- frontend/src/utils/date.ts | 12 ++++++++++-- frontend/testing/unit/utils/date.test.ts | 21 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/frontend/src/utils/date.ts b/frontend/src/utils/date.ts index a49d8c8f..b13507ad 100644 --- a/frontend/src/utils/date.ts +++ b/frontend/src/utils/date.ts @@ -20,8 +20,16 @@ export function parseDateSafe(rawValue: string | null | undefined): Date | null : [`${isoCompatible}Z`, isoCompatible, raw] for (const candidate of candidates) { - const d = new Date(candidate) - if (!Number.isNaN(d.getTime())) return d + const d = new Date(candidate) + + // 1. Check if the date is technically valid + const isValid = !Number.isNaN(d.getTime()) + + // 2. Sanity check: Ensure the year is between 1900 and 2100 + // This is what will catch the "99999" error from your screenshot + const isRealistic = isValid && d.getFullYear() > 1900 && d.getFullYear() < 2100 + + if (isRealistic) return d } } catch (error) { console.error('Date parsing failed:', error, raw) diff --git a/frontend/testing/unit/utils/date.test.ts b/frontend/testing/unit/utils/date.test.ts index 80bfe40e..06c2c2fd 100644 --- a/frontend/testing/unit/utils/date.test.ts +++ b/frontend/testing/unit/utils/date.test.ts @@ -96,4 +96,23 @@ import { expect(result.time).not.toBe("UNKNOWN TIME"); }); }); - }); \ No newline at end of file + }); + + describe("Issue #107: Invalid Date Handling", () => { + test("returns N/A for completely random strings", () => { + // This should fail initially because the current function + // might return 'Invalid Date' or crash instead of 'N/A' + expect(formatLocaleDate("not-a-date")).toBe("N/A"); + }); + + test("returns N/A for impossible calendar dates", () => { + // This catches dates that JavaScript usually 'overflows' + // like turning month 13 into next year + expect(formatLocaleDate("2026-13-45")).toBe("N/A"); + }); + + test("returns N/A for numeric strings that aren't timestamps", () => { + // Prevents random 5-digit strings from being parsed as years + expect(formatLocaleDate("99999")).toBe("N/A"); + }); +}); \ No newline at end of file From 6d3573fcd71c6457ae1c2387103225560727828d Mon Sep 17 00:00:00 2001 From: Saumya Tripathi Date: Sun, 24 May 2026 00:13:32 +0530 Subject: [PATCH 2/2] fix: refine comments and harden date validation logic #107 --- frontend/src/utils/date.ts | 1 - frontend/testing/unit/utils/date.test.ts | 33 ++++++++++++------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/frontend/src/utils/date.ts b/frontend/src/utils/date.ts index b13507ad..bbdf5567 100644 --- a/frontend/src/utils/date.ts +++ b/frontend/src/utils/date.ts @@ -26,7 +26,6 @@ export function parseDateSafe(rawValue: string | null | undefined): Date | null const isValid = !Number.isNaN(d.getTime()) // 2. Sanity check: Ensure the year is between 1900 and 2100 - // This is what will catch the "99999" error from your screenshot const isRealistic = isValid && d.getFullYear() > 1900 && d.getFullYear() < 2100 if (isRealistic) return d diff --git a/frontend/testing/unit/utils/date.test.ts b/frontend/testing/unit/utils/date.test.ts index 06c2c2fd..fc772c55 100644 --- a/frontend/testing/unit/utils/date.test.ts +++ b/frontend/testing/unit/utils/date.test.ts @@ -98,21 +98,20 @@ import { }); }); - describe("Issue #107: Invalid Date Handling", () => { - test("returns N/A for completely random strings", () => { - // This should fail initially because the current function - // might return 'Invalid Date' or crash instead of 'N/A' - expect(formatLocaleDate("not-a-date")).toBe("N/A"); - }); + describe("Issue #107: Invalid Date Handling", () => { + test("returns N/A for completely random strings", () => { + // This should fail initially because the current function + // might return 'Invalid Date' or crash instead of 'N/A' + expect(formatLocaleDate("not-a-date")).toBe("N/A"); + }); - test("returns N/A for impossible calendar dates", () => { - // This catches dates that JavaScript usually 'overflows' - // like turning month 13 into next year - expect(formatLocaleDate("2026-13-45")).toBe("N/A"); - }); - - test("returns N/A for numeric strings that aren't timestamps", () => { - // Prevents random 5-digit strings from being parsed as years - expect(formatLocaleDate("99999")).toBe("N/A"); - }); -}); \ No newline at end of file + test("returns N/A for impossible calendar dates", () => { + // This catches dates that JavaScript usually 'overflows' + expect(formatLocaleDate("2026-13-45")).toBe("N/A"); + }); + + test("returns N/A for numeric strings that aren't timestamps", () => { + // Prevents random 5-digit strings from being parsed as years + expect(formatLocaleDate("99999")).toBe("N/A"); + }); + }); \ No newline at end of file