LarpixClient/electron/node_modules/@electron-internal/extract-zip/README.md
olcxja fb6c8b6ee9
All checks were successful
Android Build / publish (push) Successful in 55s
Linux Build / publish (push) Successful in 1m6s
update electron to v43
2026-07-09 22:38:33 +02:00

96 lines
4 KiB
Markdown

# @electron-internal/extract-zip
> [!WARNING]
> **Internal to the Electron project.** This package exists to serve Electron's
> own tooling. Use from non-Electron packages is not supported: the API may
> change to suit Electron's needs, and bug reports or feature requests from
> outside use cases may be closed without action. If you need a general-purpose
> extractor, use [`extract-zip`](https://github.com/max-mapper/extract-zip).
Fast, safe, native zip extraction for Node.js. Drop-in replacement for [`extract-zip`](https://github.com/max-mapper/extract-zip).
- **Native**: Rust core via N-API, decompression runs off the event loop.
- **Fast**: ~2x faster on entry-heavy archives, never slower. See [benchmarks](#benchmarks).
- **Safe**: hardened against Zip Slip, symlink escapes, absolute paths, NUL injection, Windows reserved names, and zip bombs.
- **Zero runtime deps**: no `debug`/`yauzl`/`get-stream` in your tree.
- **Cross-platform**: prebuilt binaries for macOS, Linux (glibc/musl), and Windows (x64/arm64).
## Install
```sh
yarn add @electron-internal/extract-zip
```
## Usage
ESM only:
```js
import extract from '@electron-internal/extract-zip';
await extract('archive.zip', { dir: '/absolute/output/path' });
```
`dir` (required, absolute) is the only option. Everything else is fixed: existing
files are overwritten, archive mode bits (masked to `0o777`) and mtimes are
preserved, symlinks are created (skipped on Windows without symlink privilege),
and writes are parallelised across `min(cpus, 8)` workers. The original's
`onEntry`, `defaultDirMode`, and `defaultFileMode` are not supported, since no
consumer in the `electron` org uses them.
## Security
Every entry path is verified to land inside `dir`:
- `..` traversal is rejected and absolute paths are stripped, via the `zip` crate's audited `enclosed_name()`.
- Directories are created one component at a time without following symlinks; an entry whose path crosses a symlink is rejected.
- Symlinks are created after all files. Each target is walked against the on-disk tree and the archive's own symlink set, with relative-only hops bounded by `dir` and a hop cap, so a chain resolving outside `dir` is rejected before any link is created.
- NUL bytes and Windows reserved device names (`CON`, `AUX`, `COM1`, trailing space/dot) are rejected on every platform.
- Symlink targets are capped at 4 KiB; per-file output is capped at `max(2 x declared size, 1 MB)` to catch entries that lie about their size.
`test/security.test.js` exercises these escapes end-to-end with hand-crafted archives.
## Benchmarks
`yarn bench` (Apple M-series, Node 24, median of 5):
| Corpus | Zip size | `extract-zip` (JS) | this | Speedup |
|---|--:|--:|--:|--:|
| electron-v42.2.0-darwin-arm64 | 112 MB | 817 ms | 441 ms | 1.9x |
| 8 x 4 MB compressible | 0.1 MB | 24 ms | 3 ms | 9.4x |
| 2000 small text files | 0.4 MB | 372 ms | 199 ms | 1.9x |
| 200 incompressible files | 6.2 MB | 40 ms | 22 ms | 1.8x |
| `node_modules` | 2.9 MB | 68 ms | 37 ms | 1.9x |
Extraction runs in phases: validate paths and create directories, inflate and
write files in parallel with zlib-ng, then apply symlinks and directory
metadata. The Electron number is gated by its single 182 MB framework binary,
which can't be split further.
## Distribution
One package ships all prebuilt binaries (~2 MB gzipped): macOS
`darwin-universal`, Windows `x64`/`arm64`, and Linux `x64`/`arm64` for both glibc
and musl. `binding.js` picks the right one at load time. No
`optionalDependencies`, no postinstall, no network at install.
## Building from source
Requires a Rust toolchain (and `cmake` for zlib-ng).
```sh
yarn install
yarn build # builds index.<your-platform>.node
yarn test
```
## Releasing
Releases are driven by [semantic-release](https://semantic-release.gitbook.io/)
on every push to `main`: conventional commit messages decide the version bump,
CI builds all targets, and the fat package is published to npm via trusted
publishing. No manual version bumps or tags.
## License
BSD-2-Clause