* fix(binary-fetcher): retry zip downloads that drop mid-body The zip path of the binary fetcher (Node.js runtimes on Windows) read the response body outside any retry. fetchFromRegistry retries only until the response headers arrive, so a TLS connection that closed during the body rejected the whole install with undici's bare "terminated" error, which names no URL. The download and checksum step now runs under the same retry policy as tarball downloads: 401, 403, 404 and non-retryable network errors fail at once, anything else is retried with the configured backoff and logged through the request-retry logger. A download that still fails names its URL. The response status is now checked, so an error page is no longer hashed as the archive. The tarball downloader already retries a mid-body drop, which was checked against a server that destroys the socket after a partial body. pnpm v12 already retries zip downloads as a whole. Closes https://github.com/pnpm/pnpm/issues/17411 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(binary-fetcher): keep retry defaults and hide URL secrets in retries The install client passes every retry field, with unset ones as undefined, and `@zkochan/retry` copies undefined over its defaults, so an unset fetch-retries disabled zip retries. Undefined fields are now dropped before merging with the defaults. The request-retry event no longer carries the error message, which for a checksum mismatch embedded the raw URL, signed-URL tokens included. The checksum error itself now shows the redacted URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(binary-fetcher): reword a comment for the spell checker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@pnpm/fetching.binary-fetcher
A fetcher for binary archives
Installation
pnpm add @pnpm/fetching.binary-fetcher
Testing
Test Fixtures
The test/fixtures/ directory contains malicious ZIP files for testing path traversal protection:
| File | Entry Path | Purpose |
|---|---|---|
path-traversal.zip |
../../../.npmrc |
Tests ../ escape sequences |
absolute-path.zip |
/etc/passwd |
Tests absolute path entries |
backslash-traversal.zip |
..\..\..\evil.txt |
Tests Windows backslash traversal (Windows-only) |
These fixtures are manually crafted because AdmZip's addFile() sanitizes paths automatically.
Note: The backslash test only runs on Windows because
\is a valid filename character on Unix.
Regenerating Fixtures
node --experimental-strip-types scripts/create-fixtures.ts
License
MIT