7f897a95b047

v2.53.1 — trim words step layout + wrap RS WASM traps as CodexError

time
2026-05-17 21:55 UTC · 5 months ago
machine
koh2
parent
907aa805f36e
5 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/codex/erasure.ts+25 −2src/popup/views/CodexGenerateView.tsx+2 −20
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.53.0",4+  "version": "2.53.1",55   "description": "Zero-knowledge password manager",66   "browser_specific_settings": {77     "gecko": {

view file

manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.53.0",4+  "version": "2.53.1",55   "description": "Zero-knowledge password manager",66   "action": {77     "default_popup": "src/popup/index.html",

view file

package.json+1 −1
@@ -1,6 +1,6 @@11 {22   "name": "peach",3-  "version": "2.53.0",3+  "version": "2.53.1",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/popup/codex/erasure.ts+25 −2
@@ -107,7 +107,20 @@107107   const buffer = new Uint8Array(totalShards * CHUNK_SIZE);108108   buffer.set(data, 0); // Trailing bytes after `data.length` stay zero — the pad.109109 110-  const code = rs.encode(buffer, dataShards, parityShards);110+  let code: number;111+  try {112+    code = rs.encode(buffer, dataShards, parityShards);113+  } catch (err) {114+    // WASM traps (e.g. Rust panics) surface as raw JS errors with messages115+    // like "unreachable". Map them to a typed CodexError so the UI can116+    // explain what happened instead of leaking the trap string.117+    throw new CodexError(118+      "ERASURE_CODING_VERIFICATION_FAILED",119+      `Reed-Solomon encode trapped (data=${dataShards}, parity=${parityShards}): ${120+        err instanceof Error ? err.message : String(err)121+      }`,122+    );123+  }111124   if (code !== ReedSolomonErasure.RESULT_OK) {112125     throw new CodexError(113126       "ERASURE_CODING_VERIFICATION_FAILED",@@ -199,7 +212,17 @@199212     available[index] = true;200213   }201214 202-  const code = rs.reconstruct(buffer, dataShards, parityShards, available);215+  let code: number;216+  try {217+    code = rs.reconstruct(buffer, dataShards, parityShards, available);218+  } catch (err) {219+    throw new CodexError(220+      "ERASURE_CODING_VERIFICATION_FAILED",221+      `Reed-Solomon reconstruct trapped (data=${dataShards}, parity=${parityShards}, have=${chunks.size}): ${222+        err instanceof Error ? err.message : String(err)223+      }`,224+    );225+  }203226   if (code !== ReedSolomonErasure.RESULT_OK) {204227     // The library distinguishes "not enough shards" with its own code; map it205228     // back to our INSUFFICIENT_CHUNKS so handlers upstream can surface a

view file

src/popup/views/CodexGenerateView.tsx+2 −20
@@ -363,13 +363,8 @@363363             <div class="peach-codex-recovery-headline">364364               <h2 class="peach-codex-recovery-title">your recovery words.</h2>365365               <p class="peach-codex-recovery-body">366-                write these down and store them somewhere safe — separately367-                from your Codex.366+                write these down — store separately from your Codex.368367               </p>369-              <p class="peach-codex-recovery-warn">370-                together they restore your vault without your master371-                passphrase. keep them apart.372-              </p>373368             </div>374369 375370             <ol class="peach-codex-words-grid" start={1}>@@ -385,7 +380,7 @@385380 386381             <Show when={estimatedPages() !== null}>387382               <p class="peach-codex-meta">388-                estimated <strong>{estimatedPages()}</strong>{" "}383+                <strong>{estimatedPages()}</strong>{" "}389384                 {estimatedPages() === 1 ? "page" : "pages"} ·{" "}390385                 {snapshot()!.entryCount}{" "}391386                 {snapshot()!.entryCount === 1 ? "entry" : "entries"}@@ -393,19 +388,6 @@393388                   {" "}· {estimatedParity()} redundancy codes394389                 </Show>395390               </p>396-              <Show when={estimatedParity() !== null}>397-                <p class="peach-codex-meta peach-codex-meta-hint">398-                  can recover from loss of up to {estimatedParity()} codes399-                  anywhere in the document.400-                </p>401-              </Show>402-              <Show when={(estimatedPages() ?? 0) >= 2}>403-                <p class="peach-codex-meta peach-codex-meta-hint">404-                  this is your complete vault. print double-sided to reduce to{" "}405-                  {Math.ceil((estimatedPages() ?? 0) / 2)} sheets. store406-                  separately from your recovery words.407-                </p>408-              </Show>409391             </Show>410392 411393             <div class="peach-codex-confirm-section">

view file