Skip to content

fix(web): don't crash reading a non-object thread-layout entry - #6677

Merged
pedrofrxncx merged 1 commit into
mainfrom
fix/thread-layout-memory-non-object-entry
Aug 28, 2026
Merged

fix(web): don't crash reading a non-object thread-layout entry#6677
pedrofrxncx merged 1 commit into
mainfrom
fix/thread-layout-memory-non-object-entry

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Source: a bug found reading apps/web/src/lib/thread-layout-memory.ts (recently touched by #6667, the destination-by-path work).

Why: sanitizeThreadLayout (the boundary the module's own comment claims sanitizes every read of tampered/untrusted sessionStorage JSON) assumes its argument is an object. readStore's validation only checks the stored tuple's shape ([id, layout], id a string) — it never checks that layout itself is an object. A malformed entry such as ["a", null] (privacy-mode quirks, a manual tamper, or a future format bug) passes that filter, and sanitizeThreadLayout(null) throws a TypeError on layout.tab, which propagates out of readThreadLayout — called on every thread switch (resolveTaskSwitchSearch) — crashing that flow instead of degrading to "no memory" as the module promises.

Fix: sanitizeThreadLayout now returns {} for null/non-object input instead of throwing, matching every other tampered-value case it already handles.

Regression test: thread-layout-memory.test.ts — new case feeds null/undefined/a string/a number/an array into sanitizeThreadLayout and asserts it returns {} instead of throwing.

Reviewer command: bun test apps/web/src/lib/thread-layout-memory.test.ts

Local checks run: bun run fmt, bunx oxlint apps/web/src/lib/thread-layout-memory.ts apps/web/src/lib/thread-layout-memory.test.ts (clean), and the targeted test file above (8 pass). Skipped the workspace tsc --noEmit — it fails on a pre-existing, unrelated prosemirror version-mismatch error in mention-suggestion.tsx that predates this change. Full CI validates the rest.


Summary by cubic

Fixes a crash when reading a tampered or malformed thread-layout entry from sessionStorage. sanitizeThreadLayout now returns {} for non-object input instead of throwing, so readThreadLayout no longer blows up on entries like ["a", null] and degrades to "no memory" as the module promises. Adds a regression test covering null, undefined, strings, numbers, and arrays.

Written for commit 0364f79. Summary will update on new commits.

Review in cubic

sanitizeThreadLayout assumed its argument was an object. readStore's
own filter only checks the stored tuple's shape ([id, layout], id a
string) — it never validates that the layout half is an object, so a
tampered/malformed sessionStorage entry like ["a", null] passes the
filter and crashes sanitizeThreadLayout with a TypeError on
layout.tab, taking down readThreadLayout (and anything that calls it,
e.g. a thread switch) with it. The module's own doc comment says
stored JSON can be tampered with and every read is sanitized — this
closes that gap.
@pedrofrxncx
pedrofrxncx merged commit 4e3d40e into main Aug 28, 2026
34 checks passed
@pedrofrxncx
pedrofrxncx deleted the fix/thread-layout-memory-non-object-entry branch August 28, 2026 13:05
decocms Bot pushed a commit that referenced this pull request Aug 28, 2026
PR: #6677 fix(web): don't crash reading a non-object thread-layout entry
Bump type: patch

- decocms (apps/api/package.json): 4.291.0 -> 4.291.1
- @decocms/native (apps/native/package.json): 4.291.0 -> 4.291.1

Deploy-Scope: web
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant