diff --git a/apps/web/src/lib/thread-layout-memory.test.ts b/apps/web/src/lib/thread-layout-memory.test.ts index f146a8f9f3..7ce9465d1b 100644 --- a/apps/web/src/lib/thread-layout-memory.test.ts +++ b/apps/web/src/lib/thread-layout-memory.test.ts @@ -29,6 +29,16 @@ describe("sanitizeThreadLayout", () => { } as unknown as Parameters[0]; expect(sanitizeThreadLayout(dirty)).toEqual({}); }); + + test("doesn't throw on a non-object entry (tampered sessionStorage)", () => { + for (const dirty of [null, undefined, "chat", 5, ["a"]] as unknown[]) { + expect( + sanitizeThreadLayout( + dirty as unknown as Parameters[0], + ), + ).toEqual({}); + } + }); }); describe("upsertThreadLayoutEntries", () => { diff --git a/apps/web/src/lib/thread-layout-memory.ts b/apps/web/src/lib/thread-layout-memory.ts index bc44b143ea..6f19cf5693 100644 --- a/apps/web/src/lib/thread-layout-memory.ts +++ b/apps/web/src/lib/thread-layout-memory.ts @@ -42,6 +42,7 @@ type StoredEntry = [taskId: string, layout: ThreadLayout]; */ export function sanitizeThreadLayout(layout: ThreadLayout): ThreadLayout { const clean: ThreadLayout = {}; + if (layout === null || typeof layout !== "object") return clean; if (typeof layout.tab === "string") clean.tab = layout.tab; if (typeof layout.mainpanel === "boolean") clean.mainpanel = layout.mainpanel; if (typeof layout.sidepanel === "boolean") {