diff --git a/apps/pwa/src/components/EventForm.tsx b/apps/pwa/src/components/EventForm.tsx index a8980cf..5f10136 100644 --- a/apps/pwa/src/components/EventForm.tsx +++ b/apps/pwa/src/components/EventForm.tsx @@ -120,6 +120,14 @@ function parseDateTime(iso: string): { date: string; time: string; ok: boolean } // All-day date string — use as-is (no time component) return { date: clean, time: '09:00', ok: true } } + // WR-08: require a well-formed timed shape (date + 'T' + HH:MM) before trusting + // new Date()'s permissive parsing. Otherwise a truncated/garbled cached value like + // '2026-06' parses as a VALID UTC instant in V8 and would be saved on edit without + // tripping the IN-02 blank-field guard. A genuinely malformed timed value now fails + // here and is reported ok:false instead of silently resolving to an unintended day. + if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(clean)) { + throw new Error('Malformed timed datetime') + } const d = new Date(clean) if (isNaN(d.getTime())) throw new Error('Invalid date') // WR-05: use ONLY local accessors so date and time are in the same zone frame.