Skip to content

fix: unwrap data.bin from zip in Opened.decrypt uuid mode#67

Merged
rubenhensen merged 1 commit into
mainfrom
fix/data-bin-unwrap-39
May 13, 2026
Merged

fix: unwrap data.bin from zip in Opened.decrypt uuid mode#67
rubenhensen merged 1 commit into
mainfrom
fix/data-bin-unwrap-39

Conversation

@dobby-coder
Copy link
Copy Markdown
Contributor

@dobby-coder dobby-coder Bot commented May 13, 2026

Closes #39

Summary

  • Sealed.upload() for data: mode wraps raw bytes as a single-entry zip (data.bin), but Opened.decrypt({ uuid }) always returned the raw zip blob — so the round-trip pg.encrypt({ data }).upload()pg.open({ uuid }).decrypt() did not return { plaintext, ... } as the encrypt-side API implies.
  • Opened.decrypt now checks the central directory: if the entries are exactly ['data.bin'], it unwraps the entry and returns DecryptDataResult { plaintext, sender }. Otherwise it returns DecryptFileResult unchanged.
  • New extractZipEntry in util/zip: CDR-driven (conflux's streaming writer leaves compressedSize: 0 in the LFH, so LFH-only walking won't work) and supports stored (method 0) and deflate (method 8) via DecompressionStream('deflate-raw').

Tests

  • New: stored-entry extraction returns exact bytes.
  • New: streaming-mode deflate zip (conflux-shape — sizes only in CDR) round-trips back to the original payload.
  • New: missing entry throws.
  • Existing 86 tests still pass; total now 89.

Verified: npm run typecheck, npm test, npm run build all clean.

Reviewer quickstart

git fetch origin && git checkout fix/data-bin-unwrap-39 && npm ci && npm test

Restores symmetry with Sealed.upload() data: mode, which wraps raw bytes
as a single-entry zip named data.bin. When Opened.decrypt() sees a uuid
result whose central directory is exactly ['data.bin'], it now returns
DecryptDataResult { plaintext, sender } instead of forcing consumers to
walk the zip themselves.

Adds extractZipEntry in util/zip — CDR-driven (conflux's streaming
writer leaves compressedSize=0 in the LFH, so LFH-only walking fails)
and supports stored (method 0) and deflate (method 8) via
DecompressionStream('deflate-raw').

Closes #39
@dobby-coder dobby-coder Bot requested a review from rubenhensen May 13, 2026 16:22
@rubenhensen rubenhensen merged commit 146a7ab into main May 13, 2026
3 checks passed
@rubenhensen rubenhensen deleted the fix/data-bin-unwrap-39 branch May 13, 2026 16:29
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 1.7.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Copy link
Copy Markdown
Contributor Author

@dobby-coder dobby-coder Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed post-merge for the record. Looks good — the fix correctly restores the encrypt/decrypt round-trip symmetry for the data: mode (see #39).

Verified in the diff:

  • src/opened.ts:104-114 — unwrap only triggers on the exact single-entry ['data.bin'] shape, so multi-file uploads still return DecryptFileResult unchanged.
  • src/util/zip.ts extractZipEntry — CDR-driven, correct for conflux's streaming writer (LFH has compressedSize=0). Re-reading filename/extra lengths from the LFH (not reusing the CDR's) is also correct per spec.
  • DecompressionStream('deflate-raw') is the right primitive for method 8 raw deflate.
  • Tests cover stored (method 0), streaming-mode deflate with sizes-only-in-CDR, and missing-entry. Tight coverage for the bug class.

Minor nits (non-blocking, already merged):

  • extractZipEntry validates the LFH signature but doesn't verify the LFH filename matches the requested name. A malformed/adversarial zip with mismatched LFH-vs-CDR filenames would silently extract the wrong bytes. Low-risk since the source is our own Sealed.upload.
  • Method 8 path doesn't verify uncompressed size against entry.uncompressedSize or check CRC. Low-risk for trusted inputs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opened.decrypt should unwrap data.bin from zip in uuid mode (symmetry with Sealed.upload)

1 participant