Skip to content

refactor(cli): templates pull unpacks the verified pack from memory - #7084

Merged
WaterrrForever merged 1 commit into
mainfrom
miao/templates-unpack-stdin
Nov 3, 2026
Merged

WaterrrForever merged 1 commit into
mainfrom
miao/templates-unpack-stdin

Conversation

@WaterrrForever

Copy link
Copy Markdown
Collaborator

What

hyperframes templates pull unpacks the downloaded pack from memory: tar reads the checked bytes on stdin for both the path check and the extraction. The temporary template.tar.gz is gone.

Why

CodeQL flagged the write of downloaded bytes to disk (js/http-to-file-access, alert 1273). It was a false positive, since the bytes are checked against the pinned size and sha256 first, and was dismissed so #6842 could land. This removes the write so the pattern is not there to flag.

Related work

Follows #6842.

How

  • assertSafeEntries runs tar -tzf - with the pack as input.
  • unpack runs tar -xzf - -C <staging> --no-same-owner with the same input, then moves the folder into place as before.

Test plan

  • templates.test.ts: 8 passed (pinned pull, 402/401/503, hash mismatch, unsafe archive path, existing destination, cleanup on refusal).
  • A real 140 MB pack unpacked through stdin: 591 entries, about 5 s.
  • Windows: covered by the CI Windows test job (bsdtar reads -f -).

Size

One file, 6 added and 7 removed lines.

🤖 Generated with Claude Code

The pack was written to a temporary file before tar read it. tar now
reads the checked bytes on stdin, so nothing downloaded is written to
disk before it is unpacked.

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

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed at 8d40a1ad1baae6070281aecb7ee271b640b20b51.

The verified buffer feeds both tar invocations (packages/cli/src/commands/templates.ts:87–91,106), so listing and extraction see the same bytes without an intermediate archive file. Pinned length/SHA checks still precede tar, path validation still precedes extraction, and the staging directory remains inside try/finally cleanup with publication only after extraction succeeds (:81–83,100–110). No new blocker found in the one-file refactor.

Validation: full root bun run build passed. bun run --cwd packages/cli test src/commands/templates.test.ts reports 8 passed; oxlint reports zero errors/warnings and oxfmt --check passes. The suite executes real tar for ordinary extraction, unsafe parent paths, hash refusal, auth/plan refusal and existing destinations. Separate exact-source controls extract only assertSafeEntries/unpack and inject Node built-ins (they bypass HTTP/auth/hash checks): 11 scenarios × base/head × Node/Bun = 44 invocations. Ordinary and synthetic 140,711,403-byte archives pass; corrupt/truncated input, unsafe paths and an archive that writes a then fails extracting a/b leave no destination or staging directories. These include actual extraction failure, rather than only list-time refusal. I inspected the probe and reran the 22 Node invocations. The synthetic large archive is not the private production pack.

Bounded behavior difference: at templates.ts:88–92, Node can report EPIPE if tar exits successfully before consuming large store-compressed trailing padding or concatenated gzip members. The file-input base succeeds on those synthetic cases; Bun did not show that difference. No evidence shows that layout in any of the five pinned packs, so I do not treat it as a demonstrated shipped regression. The parity claim is limited to the exercised ordinary-pack cases; future pack publication should retain an stdin extraction check.

Limits: local Node 22.22.3 / GNU tar 1.30 only; no Windows run or live production pull by me; the author's real 140 MB pack result is not my reproduction. This review does not claim a general audit of tar/archive trust or re-verify plan enforcement.

Need: yes · Size: one-file refactor · Reuse: existing verified buffer and Node execFileSync input · Simpler: removes temporary archive write · Structure: fine
Risk: low — narrow change to the pinned-pack workflow, with Windows execution not independently verified.

Verdict: APPROVE
Reasoning: Both tar calls consume the verified bytes and preserve the exercised validation/publication/cleanup behavior.

— hf-review

@WaterrrForever
WaterrrForever added this pull request to the merge queue Nov 3, 2026
@WaterrrForever
WaterrrForever removed this pull request from the merge queue due to a manual request Nov 3, 2026
@WaterrrForever
WaterrrForever added this pull request to the merge queue Nov 3, 2026
@WaterrrForever
WaterrrForever removed this pull request from the merge queue due to a manual request Nov 3, 2026
@WaterrrForever
WaterrrForever added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit faae601 Nov 3, 2026
110 of 111 checks passed
@WaterrrForever
WaterrrForever deleted the miao/templates-unpack-stdin branch November 3, 2026 16:45
This was referenced Nov 4, 2026
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.

2 participants