Skip to content

Extract the release archive without shelling out to tar#134

Merged
YurMil merged 1 commit into
mainfrom
fix/portable-archive-extraction
Jul 22, 2026
Merged

Extract the release archive without shelling out to tar#134
YurMil merged 1 commit into
mainfrom
fix/portable-archive-extraction

Conversation

@YurMil

@YurMil YurMil commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Fixes the first automatic release, which reached the host and then died on extraction:

[whisper-transcriber] Archive checksum verified: a1ebc4ce…
tar: This does not look like a tar archive

Cause

The sync shelled out to tar -xf for a zip. That works on Windows and macOS, where tar is bsdtar and reads zip, and fails on Linux, where it is GNU tar and does not. It passed my local testing purely because I tested it on Windows — "call the system tar" was never portable, it just matched the machine it was written on.

Everything before extraction worked correctly: the release was built, packaged, dispatched, downloaded and its checksum verified.

Fix

Zip reading now happens in Node with zlib. No dependency on which archiver a host has installed, identical behaviour everywhere, and unsafe entries are rejected before anything is written instead of being caught by the audit afterwards.

Deliberately minimal — store and deflate, no zip64, no encryption. The archives come from our own release workflow, and anything else should be refused loudly rather than half-understood.

Verification

Run against the actual archive from the failed run:

  • all six entries extract byte-identically to Windows Expand-Archive, an independent implementation — including the 21 MB wasm. Hand-rolled zip parsing deserves a second opinion, so it got one.
  • a crafted archive containing ../evil.txt is rejected with nothing written outside the target directory;
  • both that and a checksum mismatch exit non-zero, so the workflow fails rather than publishing something unverified.

No artifact is included here on purpose: once this is merged, re-running the failed sync will publish it, which is the pipeline doing its job.

Ordering

#133 (rolling sync branch) is still open and independent of this. Either order works.

🤖 Generated with Claude Code

The first automatic release failed on the host: "tar: This does not look like a
tar archive". Shelling out to `tar -xf` for a zip only ever worked because the
machine it was written on was Windows, where tar is bsdtar and reads zip. The
runner is Linux, where tar is GNU tar and does not.

Nothing about calling the system archiver was portable, so it is gone. Zip
reading now happens in Node with zlib, which behaves the same everywhere and
lets unsafe entries be rejected before anything is written rather than after.

Deliberately minimal — store and deflate, no zip64, no encryption. The archives
come from our own release workflow, and anything else should be refused loudly
rather than half-understood.

Verified against the archive from the failed run: all six entries extract
byte-identically to an independent implementation (Windows Expand-Archive),
including the 21 MB wasm. A crafted archive containing "../evil.txt" is
rejected with nothing written outside the target, and both that and a checksum
mismatch exit non-zero so the workflow fails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cadautoscript-com Ready Ready Preview, Comment Jul 22, 2026 4:16pm

@supabase

supabase Bot commented Jul 22, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project bkcimygtsnckzexbfqxh because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@YurMil
YurMil merged commit 4237713 into main Jul 22, 2026
8 checks passed
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