tar-xz 6.0.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +159 -0
- package/README.md +30 -1
- package/SECURITY.md +103 -0
- package/lib/browser/extract.d.ts.map +1 -1
- package/lib/browser/extract.js +21 -6
- package/lib/browser/extract.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/node/extract.d.ts +2 -2
- package/lib/node/extract.d.ts.map +1 -1
- package/lib/node/extract.js +270 -117
- package/lib/node/extract.js.map +1 -1
- package/lib/node/file.d.ts +24 -3
- package/lib/node/file.d.ts.map +1 -1
- package/lib/node/file.js +338 -132
- package/lib/node/file.js.map +1 -1
- package/lib/node/list.d.ts +1 -0
- package/lib/node/list.d.ts.map +1 -1
- package/lib/node/list.js +9 -64
- package/lib/node/list.js.map +1 -1
- package/lib/node/tar-parser.d.ts +38 -0
- package/lib/node/tar-parser.d.ts.map +1 -1
- package/lib/node/tar-parser.js +177 -7
- package/lib/node/tar-parser.js.map +1 -1
- package/lib/node/xz-helpers.d.ts +19 -8
- package/lib/node/xz-helpers.d.ts.map +1 -1
- package/lib/node/xz-helpers.js +61 -55
- package/lib/node/xz-helpers.js.map +1 -1
- package/lib/tar/checksum.d.ts.map +1 -1
- package/lib/tar/checksum.js +8 -1
- package/lib/tar/checksum.js.map +1 -1
- package/lib/tar/format.d.ts +0 -6
- package/lib/tar/format.d.ts.map +1 -1
- package/lib/tar/format.js +36 -17
- package/lib/tar/format.js.map +1 -1
- package/lib/types.d.ts +22 -0
- package/lib/types.d.ts.map +1 -1
- package/package.json +15 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# tar-xz
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [6.1.1] - 2026-05-06
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- enrich package metadata (description + keywords) for 3 packages (#141) ([5f0bb5b](https://github.com/oorabona/node-liblzma/commit/5f0bb5b))
|
|
9
|
+
- document TarEntryTypeValue with JSDoc + expose in index (#137) (tar-xz) ([fe56124](https://github.com/oorabona/node-liblzma/commit/fe56124))
|
|
10
|
+
- add tar-xz API and nxz CLI to GitHub Pages (#133) (pages) ([2c22298](https://github.com/oorabona/node-liblzma/commit/2c22298))
|
|
11
|
+
- close 7 final coverage partials to reach 100% (#131) (tar-xz) ([0830fac](https://github.com/oorabona/node-liblzma/commit/0830fac))
|
|
12
|
+
- close 7 coverage partials with surgical v8 ignores (#130) (tar-xz) ([de86c0c](https://github.com/oorabona/node-liblzma/commit/de86c0c))
|
|
13
|
+
- close extract.ts coverage partials with v8 ignores (#129) (tar-xz) ([3abb041](https://github.com/oorabona/node-liblzma/commit/3abb041))
|
|
14
|
+
- close file.ts coverage partials with tests + v8 ignores (#128) (tar-xz) ([8e51020](https://github.com/oorabona/node-liblzma/commit/8e51020))
|
|
15
|
+
- cover three trivial file.ts branches (mtime=0, FILE type, mode=0) (#126) (tar-xz) ([5c496f8](https://github.com/oorabona/node-liblzma/commit/5c496f8))
|
|
16
|
+
- close remaining coverage gaps to 100% lines (#125) (tar-xz) ([7189f8e](https://github.com/oorabona/node-liblzma/commit/7189f8e))
|
|
17
|
+
- cover toAsyncIterable across Node and Browser variants (#124) (tar-xz) ([8c0f994](https://github.com/oorabona/node-liblzma/commit/8c0f994))
|
|
18
|
+
- wrap defensive-unreachable branches with v8 ignore start/stop (#123) (tar-xz) ([add1724](https://github.com/oorabona/node-liblzma/commit/add1724))
|
|
19
|
+
- remove dead biome suppression in tar-xz node-api spec (#119) (lint) ([49c7f14](https://github.com/oorabona/node-liblzma/commit/49c7f14))
|
|
20
|
+
- biome warnings sweep + cognitive-complexity extract-method (63→1) (#115) ([ad2e18f](https://github.com/oorabona/node-liblzma/commit/ad2e18f))
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- use absolute URLs in typedoc navigationLinks (#136) (docs) ([cd1185c](https://github.com/oorabona/node-liblzma/commit/cd1185c))
|
|
24
|
+
- include CHANGELOG.md and SECURITY.md in published tarball (tar-xz) ([408e955](https://github.com/oorabona/node-liblzma/commit/408e955))
|
|
25
|
+
|
|
26
|
+
## [6.1.0] - 2026-04-29
|
|
27
|
+
|
|
28
|
+
### ⚠️ BREAKING CHANGES
|
|
29
|
+
- redesign for v6 — universal stream-first API (#108) (tar-xz) ([b2c8a8c](https://github.com/oorabona/node-liblzma/commit/b2c8a8c))
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- true streaming for Node extract()/list() — O(largest entry) (#113) (tar-xz) ([06a9937](https://github.com/oorabona/node-liblzma/commit/06a9937))
|
|
33
|
+
- wire memlimit through N-API decoder (#112) (native) ([0d09200](https://github.com/oorabona/node-liblzma/commit/0d09200))
|
|
34
|
+
- wire memlimit option through unxzAsync/unxz (#111) (wasm) ([6e2bc09](https://github.com/oorabona/node-liblzma/commit/6e2bc09))
|
|
35
|
+
- adopt Changesets for monorepo versioning + changelog generation (ci) ([adfbc99](https://github.com/oorabona/node-liblzma/commit/adfbc99))
|
|
36
|
+
- redesign for v6 — universal stream-first API (#108) (tar-xz) ⚠️ BREAKING ([b2c8a8c](https://github.com/oorabona/node-liblzma/commit/b2c8a8c))
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
- close Win32 symlink-swap TOCTOU with JS-pure 'wx'+retry fail-closed (#114) (tar-xz) ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
40
|
+
- re-add @changesets/cli (was clobbered by pnpm add of changelog-github) (deps) ([6d76280](https://github.com/oorabona/node-liblzma/commit/6d76280))
|
|
41
|
+
- use 'changeset' so the bin resolves with --ignore-scripts (ci) ([78b91f7](https://github.com/oorabona/node-liblzma/commit/78b91f7))
|
|
42
|
+
- toAsyncIterable mis-dispatched Uint8Array via Symbol.iterator ([b2c8a8c](https://github.com/oorabona/node-liblzma/commit/b2c8a8c))
|
|
43
|
+
- use always() in publish job to bypass skipped build (workspace target) (ci) ([2e08977](https://github.com/oorabona/node-liblzma/commit/2e08977))
|
|
44
|
+
- pin pnpm/action-setup to v5 in refresh-lockfile (v6 corrupts lockfile) (ci) ([f39d603](https://github.com/oorabona/node-liblzma/commit/f39d603))
|
|
45
|
+
- regenerate pnpm-lock.yaml (was broken with duplicate YAML document) (deps) ([e0c66ab](https://github.com/oorabona/node-liblzma/commit/e0c66ab))
|
|
46
|
+
- use squash merge in Dependabot auto-merge (linear history required) (ci) ([f3aee60](https://github.com/oorabona/node-liblzma/commit/f3aee60))
|
|
47
|
+
- point tar-xz demo Vite alias to browser entry ([8aea7ac](https://github.com/oorabona/node-liblzma/commit/8aea7ac))
|
|
48
|
+
- point demo Vite alias to browser entry (fixes docs build) ([e86dba5](https://github.com/oorabona/node-liblzma/commit/e86dba5))
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- finalize WIN32-TOCTOU-2026-04-29 — promote spec, mark TODO done ([1ee9db4](https://github.com/oorabona/node-liblzma/commit/1ee9db4))
|
|
52
|
+
- node-tar is pure JS and explicitly does NOT protect Windows ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
53
|
+
- 0 errors. Type-check: 0 errors. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
54
|
+
- 155 pass / 0 fail / 3 pre-existing skips. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
55
|
+
- 0 errors. Type-check: 0 errors. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
56
|
+
- 155 pass / 0 fail / 3 pre-existing skips (identical to pre-fix). ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
57
|
+
- 0 errors. Type-check: 0 errors. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
58
|
+
- round 1 = 6 findings (3 M + 2 L + 1 misclassified), round 2 ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
59
|
+
- 155 pass / 0 fail / 3 pre-existing skips. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
60
|
+
- 0 errors. Type-check: 0 errors. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
61
|
+
- round 1 = 6 findings, round 2 = 3, round 3 = 1, round 4 ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
62
|
+
- 155 pass / 0 fail / 3 pre-existing skips. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
63
|
+
- 0 errors. Type-check: 0 errors. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
64
|
+
- round 1=6, round 2=3, round 3=1, round 4=3 (2 real Ms in ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
65
|
+
- 155 pass / 0 fail / 3 pre-existing skips. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
66
|
+
- 0 errors. Type-check: 0 errors. ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
67
|
+
- round 1=6, round 2=3, round 3=1, round 4=3 (2 real Ms ([b24040d](https://github.com/oorabona/node-liblzma/commit/b24040d))
|
|
68
|
+
- refresh lockfile for latest transitive dependencies (deps) ([06e9590](https://github.com/oorabona/node-liblzma/commit/06e9590))
|
|
69
|
+
- finally swallows cleanup errors on consumer-break, ([06a9937](https://github.com/oorabona/node-liblzma/commit/06a9937))
|
|
70
|
+
- 150+3-skip pass; memory 3+1-skip pass. tsc + lint + build green. ([06a9937](https://github.com/oorabona/node-liblzma/commit/06a9937))
|
|
71
|
+
- refresh lockfile for latest transitive dependencies (deps) ([f8f21d0](https://github.com/oorabona/node-liblzma/commit/f8f21d0))
|
|
72
|
+
- - release-it (existing release.yml + .release-it.json) is retained for ([adfbc99](https://github.com/oorabona/node-liblzma/commit/adfbc99))
|
|
73
|
+
- capture tar-xz v6 redesign in CHANGELOGs + TODO.md ([9abd0a2](https://github.com/oorabona/node-liblzma/commit/9abd0a2))
|
|
74
|
+
- test fails on revert, passes on fix. ([b2c8a8c](https://github.com/oorabona/node-liblzma/commit/b2c8a8c))
|
|
75
|
+
- release v5.0.1 (tar-xz) ([0c631f5](https://github.com/oorabona/node-liblzma/commit/0c631f5))
|
|
76
|
+
- sync workspace package versions to npm registry (3.2.0 -> 5.0.0) ([900a055](https://github.com/oorabona/node-liblzma/commit/900a055))
|
|
77
|
+
- refresh lockfile for latest transitive dependencies (deps) ([8345c25](https://github.com/oorabona/node-liblzma/commit/8345c25))
|
|
78
|
+
- propagate anti-flake cleanup pattern to 3 high-risk integration tests ([f752664](https://github.com/oorabona/node-liblzma/commit/f752664))
|
|
79
|
+
- add afterEach cleanup + timer tracking in error_recovery test (anti-flake) ([2d7f285](https://github.com/oorabona/node-liblzma/commit/2d7f285))
|
|
80
|
+
- refresh lockfile for latest transitive dependencies (deps) ([bc7e804](https://github.com/oorabona/node-liblzma/commit/bc7e804))
|
|
81
|
+
- refresh lockfile for latest transitive dependencies (deps) ([dedd2c1](https://github.com/oorabona/node-liblzma/commit/dedd2c1))
|
|
82
|
+
- bump @vitest/ui (#106) (deps-dev) ([276f0b4](https://github.com/oorabona/node-liblzma/commit/276f0b4))
|
|
83
|
+
- refresh lockfile for latest transitive dependencies (deps) ([8b7b5b9](https://github.com/oorabona/node-liblzma/commit/8b7b5b9))
|
|
84
|
+
- ignore pnpm/action-setup v6+ in Dependabot (corrupts lockfile) (ci) ([fd2cf8c](https://github.com/oorabona/node-liblzma/commit/fd2cf8c))
|
|
85
|
+
- refresh lockfile for latest transitive dependencies (deps) ([a01694e](https://github.com/oorabona/node-liblzma/commit/a01694e))
|
|
86
|
+
- refresh lockfile for latest transitive dependencies (deps) ([e2eca27](https://github.com/oorabona/node-liblzma/commit/e2eca27))
|
|
87
|
+
- refresh lockfile for latest transitive dependencies (deps) ([b1386e9](https://github.com/oorabona/node-liblzma/commit/b1386e9))
|
|
88
|
+
- refresh lockfile for latest transitive dependencies (deps) ([1ba850e](https://github.com/oorabona/node-liblzma/commit/1ba850e))
|
|
89
|
+
- refresh lockfile for latest transitive dependencies (deps) ([e66f8fb](https://github.com/oorabona/node-liblzma/commit/e66f8fb))
|
|
90
|
+
- refresh lockfile for latest transitive dependencies (deps) ([fd906d6](https://github.com/oorabona/node-liblzma/commit/fd906d6))
|
|
91
|
+
- refresh lockfile for latest transitive dependencies (deps) ([e085fa4](https://github.com/oorabona/node-liblzma/commit/e085fa4))
|
|
92
|
+
- bump @vitest/ui in the dev-dependencies group (#95) (deps-dev) ([01e828c](https://github.com/oorabona/node-liblzma/commit/01e828c))
|
|
93
|
+
- refresh lockfile for latest transitive dependencies (deps) ([cfe60ca](https://github.com/oorabona/node-liblzma/commit/cfe60ca))
|
|
94
|
+
- refresh lockfile for latest transitive dependencies (deps) ([1d0dd42](https://github.com/oorabona/node-liblzma/commit/1d0dd42))
|
|
95
|
+
- refresh lockfile for latest transitive dependencies (deps) ([775ed0f](https://github.com/oorabona/node-liblzma/commit/775ed0f))
|
|
96
|
+
- refresh lockfile for latest transitive dependencies (deps) ([9a66903](https://github.com/oorabona/node-liblzma/commit/9a66903))
|
|
97
|
+
- refresh lockfile for latest transitive dependencies (deps) ([3e2bd44](https://github.com/oorabona/node-liblzma/commit/3e2bd44))
|
|
98
|
+
- refresh lockfile for latest transitive dependencies (deps) ([d3bea99](https://github.com/oorabona/node-liblzma/commit/d3bea99))
|
|
99
|
+
|
|
100
|
+
### Removed
|
|
101
|
+
- - extractToMemory() — replaced by extract() + entry.bytes() ([b2c8a8c](https://github.com/oorabona/node-liblzma/commit/b2c8a8c))
|
|
102
|
+
|
|
103
|
+
## 6.0.0
|
|
104
|
+
|
|
105
|
+
### Major Changes
|
|
106
|
+
|
|
107
|
+
Complete API redesign. Universal stream-first design — same signatures in Node and Browser, built around `AsyncIterable<Uint8Array>`.
|
|
108
|
+
|
|
109
|
+
#### New API
|
|
110
|
+
|
|
111
|
+
- **Universal `create()`, `extract()`, `list()`** — identical signatures across Node and Browser.
|
|
112
|
+
- **`tar-xz/file` subpath export** (Node only) — opt-in path-based helpers `createFile()`, `extractFile()`, `listFile()`. Keeps the core SRP-clean (no fs deps in the core).
|
|
113
|
+
- **`AsyncIterable<TarEntryWithData>`** from `extract()` — entries yielded lazily; each carries a streaming `data` AsyncIterable plus `bytes()` and `text()` collector helpers.
|
|
114
|
+
- **`TarInput` union type** — accepts `AsyncIterable<Uint8Array>`, `Iterable<Uint8Array>`, `Uint8Array`, `ArrayBuffer`, `ReadableStream<Uint8Array>` (Web), or `NodeJS.ReadableStream`.
|
|
115
|
+
|
|
116
|
+
#### Security hardening
|
|
117
|
+
|
|
118
|
+
Comprehensive symlink/path TOCTOU hardening (18 vectors audited and closed in a single consolidated commit, after 7 rounds of Copilot review):
|
|
119
|
+
|
|
120
|
+
- Leaf symlink check (`target` itself, not just ancestors).
|
|
121
|
+
- Ancestor symlink walk extended to FILE/DIRECTORY/SYMLINK/HARDLINK.
|
|
122
|
+
- ENOENT correctly continues the ancestor walk instead of stopping.
|
|
123
|
+
- Hardlink `linkSource` validated for symlink-leaf and symlink-ancestor.
|
|
124
|
+
- `strip` option applied to both `name` and `linkname`.
|
|
125
|
+
- Empty / NUL-bearing names and linknames rejected.
|
|
126
|
+
- Dot-segment placeholder names (`.`, `./`, `..`) rejected.
|
|
127
|
+
- Setuid/setgid/sticky bits stripped from extracted modes by default (mirrors GNU tar `--no-same-permissions`).
|
|
128
|
+
- File extraction uses `fs.open(O_NOFOLLOW)` + fd-based `chmod`/`utimes` on POSIX — eliminates by-path TOCTOU window for permissions/timestamps.
|
|
129
|
+
- `pipeline()` instead of `pipe()` so source errors propagate properly.
|
|
130
|
+
- Threat-model documentation: concurrent attacker process is explicitly out of scope (POSIX `openat2(RESOLVE_BENEATH)` not exposed by Node).
|
|
131
|
+
|
|
132
|
+
#### Removed
|
|
133
|
+
|
|
134
|
+
- `extractToMemory()` — replaced by `extract()` + `entry.bytes()`.
|
|
135
|
+
- `createTarXz()` / `extractTarXz()` / `listTarXz()` (browser-prefixed names) — replaced by unified `create()` / `extract()` / `list()`.
|
|
136
|
+
- `BrowserCreateOptions` / `BrowserExtractOptions` — unified into single `CreateOptions` / `ExtractOptions`.
|
|
137
|
+
- `ExtractedFile` — replaced by `TarEntryWithData`.
|
|
138
|
+
|
|
139
|
+
#### Changed
|
|
140
|
+
|
|
141
|
+
- Source files for `create()` use the new `TarSourceFile` shape: `{ name, source, mode?, mtime?, linkname? }`. `source` accepts `AsyncIterable<Uint8Array> | Uint8Array | ArrayBuffer | string` (string is a Node-only fs path).
|
|
142
|
+
- `TarPack` / `TarUnpack` Transform classes are now internal; not exported from the package root.
|
|
143
|
+
- Default compression preset is uniform: `6` (Node and Browser).
|
|
144
|
+
|
|
145
|
+
#### Migration v5 → v6
|
|
146
|
+
|
|
147
|
+
See [README.md § Migration v5 → v6](./README.md#migration-v5--v6) for full code examples.
|
|
148
|
+
|
|
149
|
+
## 5.0.1
|
|
150
|
+
|
|
151
|
+
### Patch Changes
|
|
152
|
+
|
|
153
|
+
- Workspace package versions synchronized to npm registry (3.2.0 → 5.0.0). Internal infrastructure updates (CI workflows, lockfile maintenance, anti-flake test cleanup). No API changes.
|
|
154
|
+
|
|
155
|
+
[Unreleased]: https://github.com/oorabona/node-liblzma/compare/v6.1.1...HEAD
|
|
156
|
+
[v6.1.0]: https://github.com/oorabona/node-liblzma/releases/tag/v6.1.0
|
|
157
|
+
[6.1.0]: https://github.com/oorabona/node-liblzma/releases/tag/v6.1.0
|
|
158
|
+
[v6.1.1]: https://github.com/oorabona/node-liblzma/releases/tag/v6.1.1
|
|
159
|
+
[6.1.1]: https://github.com/oorabona/node-liblzma/releases/tag/v6.1.1
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ function names in both environments.
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- **Unified API** — `create`, `extract`, `list` work identically in Node.js and browsers
|
|
15
|
-
- **Stream-shaped API** — all functions return `AsyncIterable<…>`; stream-shaped inputs accepted.
|
|
15
|
+
- **Stream-shaped API** — all functions return `AsyncIterable<…>`; stream-shaped inputs accepted. Node `extract()`/`list()` now stream chunks as XZ decompresses them — memory stays O(largest single entry). v6.0.0 introduced the stream-first API contract; v6.1.0 delivers the planned optimization that fulfills it.
|
|
16
16
|
- **Flexible input** — `extract()` and `list()` accept `AsyncIterable`, `Uint8Array`,
|
|
17
17
|
`ArrayBuffer`, Web `ReadableStream`, or Node `ReadableStream`
|
|
18
18
|
- **Flexible source** — `create()` accepts fs paths (Node), `Buffer`/`Uint8Array`, or
|
|
@@ -178,6 +178,35 @@ for (const entry of entries) {
|
|
|
178
178
|
Do not import `tar-xz/file` in browser bundles — it imports `node:fs` and will
|
|
179
179
|
fail at runtime. Use `create`/`extract`/`list` directly in browser code.
|
|
180
180
|
|
|
181
|
+
## Security model
|
|
182
|
+
|
|
183
|
+
`extractFile` enforces layered path-safety checks before writing any bytes to
|
|
184
|
+
disk: traversal detection (`..` and absolute paths), leaf-symlink rejection
|
|
185
|
+
(`O_NOFOLLOW` on POSIX), ancestor-symlink TOCTOU guard, hardlink validation,
|
|
186
|
+
NUL/empty name rejection, and setuid/setgid/sticky-bit stripping.
|
|
187
|
+
|
|
188
|
+
The TOCTOU mitigation differs by platform:
|
|
189
|
+
|
|
190
|
+
**POSIX (Linux, macOS):** FILE entries are written through a file descriptor
|
|
191
|
+
opened with `O_NOFOLLOW`. The fd is held open for the entire streaming write,
|
|
192
|
+
so the window between the safety check and the last write is effectively zero.
|
|
193
|
+
|
|
194
|
+
**Windows:** `O_NOFOLLOW` is not available. Extraction falls back to by-path
|
|
195
|
+
stream operations (`createWriteStream`). With streaming delivery (v6.1.0), the
|
|
196
|
+
window between the initial safety check and the last written byte scales with
|
|
197
|
+
the entry's size — a co-tenant process that can modify `cwd` could race a
|
|
198
|
+
symlink swap during this window.
|
|
199
|
+
|
|
200
|
+
**Windows recommendation:** always extract to a directory owned exclusively by
|
|
201
|
+
the calling process. Do not extract user-supplied archives into shared,
|
|
202
|
+
world-writable, or `TEMP`-like directories on Windows.
|
|
203
|
+
|
|
204
|
+
This gap is now closed: the Windows path uses `open(target, 'wx')` (atomic
|
|
205
|
+
exclusive create) with an unlink+retry pattern for legitimate overwrites. If a symlink
|
|
206
|
+
is injected between the unlink and the retry-open, extraction fails with a security error.
|
|
207
|
+
All writes and metadata operations are fd-based. See [SECURITY.md](./SECURITY.md#windows-symlink-swap-toctou)
|
|
208
|
+
for the full reparse-tag coverage table and user mitigations.
|
|
209
|
+
|
|
181
210
|
## Streaming Patterns
|
|
182
211
|
|
|
183
212
|
### Hash while creating
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# tar-xz Security Notes
|
|
2
|
+
|
|
3
|
+
## Windows symlink-swap TOCTOU
|
|
4
|
+
|
|
5
|
+
### Background
|
|
6
|
+
|
|
7
|
+
On POSIX (Linux, macOS), `extractFile` opens each regular-file entry with
|
|
8
|
+
`O_NOFOLLOW` (`O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW`). This ensures the
|
|
9
|
+
kernel refuses to open a symlink at the leaf path, closing the symlink-swap
|
|
10
|
+
attack window from the moment the file handle is opened.
|
|
11
|
+
|
|
12
|
+
On Windows, `O_NOFOLLOW` is not available (libuv/Win32 does not expose it).
|
|
13
|
+
Prior to this hardening, the Windows path used `createWriteStream(target)` — a
|
|
14
|
+
by-path operation that could be redirected by a symlink injected between the
|
|
15
|
+
upstream safety check and the final write.
|
|
16
|
+
|
|
17
|
+
### What changed in this hardening
|
|
18
|
+
|
|
19
|
+
The Windows extraction path now uses `open(target, 'wx', mode)` — the `'wx'`
|
|
20
|
+
flag maps to `O_CREAT | O_EXCL` in libuv, an atomic "create or fail" syscall.
|
|
21
|
+
Writes, `chmod`, and `utimes` are all performed through the resulting
|
|
22
|
+
`FileHandle`, immune to any by-path swap after the open.
|
|
23
|
+
|
|
24
|
+
The full sequence:
|
|
25
|
+
|
|
26
|
+
1. **First `open('wx')`** — succeeds if the target does not exist (no prior
|
|
27
|
+
file or symlink at that path). All subsequent I/O via the file descriptor.
|
|
28
|
+
2. **`EEXIST` on first open** — a regular file exists (legitimate re-extract
|
|
29
|
+
case): call `unlink(target)` then retry `open('wx')`.
|
|
30
|
+
3. **`EEXIST` on retry** — a symlink (or other reparse point) was injected
|
|
31
|
+
between our `unlink` and our retry-open. Extraction is rejected with a
|
|
32
|
+
security error citing the entry name. No bytes are written.
|
|
33
|
+
|
|
34
|
+
### Closed attack windows
|
|
35
|
+
|
|
36
|
+
| Window | From → To | Status |
|
|
37
|
+
|--------|-----------|--------|
|
|
38
|
+
| W1 | `lstat` check → `open()` | Closed — atomic `'wx'` EEXIST-path detects injection |
|
|
39
|
+
| W2 | `open()` → last byte written | Closed — fd-based `handle.write()` follows the inode, not the path |
|
|
40
|
+
| W3 | last byte → `chmod` | Closed — `handle.chmod()` (fd-based) |
|
|
41
|
+
| W4 | `chmod` → `utimes` | Closed — `handle.utimes()` (fd-based) |
|
|
42
|
+
|
|
43
|
+
### Residual race
|
|
44
|
+
|
|
45
|
+
The `open()` syscall itself is atomic at the OS level (sub-microsecond). A
|
|
46
|
+
symlink injected **during** the `open()` syscall cannot win — the kernel either
|
|
47
|
+
creates the new inode or returns `EEXIST` atomically. There is no window inside
|
|
48
|
+
`open()`.
|
|
49
|
+
|
|
50
|
+
### Reparse-point coverage table
|
|
51
|
+
|
|
52
|
+
Windows supports several reparse-point types beyond `IO_REPARSE_TAG_SYMLINK`.
|
|
53
|
+
The table below documents what each type means for the `'wx'` fail-closed contract:
|
|
54
|
+
|
|
55
|
+
| Reparse tag | Detected by `lstat().isSymbolicLink()` | Behavior under `'wx'` | Risk level |
|
|
56
|
+
|-------------|----------------------------------------|----------------------|------------|
|
|
57
|
+
| `IO_REPARSE_TAG_SYMLINK` | **Yes** — rejected by upstream `ensureSafeTarget` before `'wx'` is attempted | n/a (caught upstream) | None |
|
|
58
|
+
| `IO_REPARSE_TAG_MOUNT_POINT` (NTFS junction) | **No** — `lstat` returns `isSymbolicLink() === false` for junctions | `'wx'` returns `EEXIST` → `unlink` removes the junction → retry `'wx'` succeeds or attacker re-injects → security error | **Leaf protected** by `'wx'` EEXIST fail-closed |
|
|
59
|
+
| OneDrive / cloud-files placeholders (`IO_REPARSE_TAG_CLOUD_FILES`, etc.) | **No** — cloud stubs look like regular files to `lstat` | `'wx'` returns `EEXIST` → handled via normal overwrite path (unlink + retry) | Low — cloud stubs are regular-file-like; write lands on the stub, which hydrates on access |
|
|
60
|
+
| `IO_REPARSE_TAG_AF_UNIX` | **No** | `'wx'` returns `EEXIST` → unlink + retry path | Low — same as junction path |
|
|
61
|
+
|
|
62
|
+
**Summary:** The only reparse type that can be present at the *leaf* target
|
|
63
|
+
path and bypasses `isSymbolicLink()` is `IO_REPARSE_TAG_MOUNT_POINT`
|
|
64
|
+
(NTFS junctions). The `'wx'` fail-closed pattern protects the leaf in all
|
|
65
|
+
cases — if an attacker injects a junction between `unlink` and the retry-open,
|
|
66
|
+
`'wx'` returns `EEXIST` and we throw the security error.
|
|
67
|
+
|
|
68
|
+
**Ancestor junctions (residual risk):** The upstream `hasSymlinkAncestor`
|
|
69
|
+
walk uses `lstat().isSymbolicLink()` and does not detect junctions in ancestor
|
|
70
|
+
directories. This is a pre-existing limitation shared by `node-tar` and other
|
|
71
|
+
pure-JS tar libraries. It is not introduced by this change. See "User
|
|
72
|
+
mitigations" below.
|
|
73
|
+
|
|
74
|
+
### Notes on hardlinks, case-insensitive NTFS, and ADS
|
|
75
|
+
|
|
76
|
+
**Hardlinks:** A hardlink injected during the unlink+retry race creates a
|
|
77
|
+
directory entry at the target path. Our retry `'wx'` returns `EEXIST` →
|
|
78
|
+
security error (fail-closed). Pre-existing hardlinks are regular files that
|
|
79
|
+
share an inode; `unlink` decrements the link count and our `'wx'` creates a
|
|
80
|
+
new inode. Semantically correct.
|
|
81
|
+
|
|
82
|
+
**Case-insensitive NTFS:** All path operations resolve to the same directory
|
|
83
|
+
entry regardless of case. This is not a bypass vector — `path.resolve` produces
|
|
84
|
+
a canonical path that is used consistently.
|
|
85
|
+
|
|
86
|
+
**NTFS Alternate Data Streams (ADS):** Out of scope. ADS does not affect the
|
|
87
|
+
default data stream. Tar entry names containing `:` are rejected upstream by
|
|
88
|
+
path-traversal validation before reaching this code.
|
|
89
|
+
|
|
90
|
+
### User mitigations
|
|
91
|
+
|
|
92
|
+
For environments where even the residual ancestor-junction risk is unacceptable:
|
|
93
|
+
|
|
94
|
+
1. **Restricted-ACL temp directory** — extract under a directory with an ACL
|
|
95
|
+
that prevents other users/processes from creating files or junctions inside
|
|
96
|
+
it. On Windows, use `CreateDirectory` + `SetSecurityInfo` to set a DACL
|
|
97
|
+
that grants write access only to the calling process's SID.
|
|
98
|
+
2. **Prefer WSL for untrusted archives** — Windows Subsystem for Linux uses
|
|
99
|
+
the Linux VFS with full `O_NOFOLLOW` support. `extractFile` on WSL takes the
|
|
100
|
+
POSIX branch and is fully protected.
|
|
101
|
+
3. **Verify archive origin** — do not extract archives from untrusted sources
|
|
102
|
+
into directories writable by other processes (world-writable temp dirs,
|
|
103
|
+
shared application data folders, etc.).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/browser/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EAEd,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/browser/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EAEd,MAAM,aAAa,CAAC;AAwFrB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAuB,OAAO,CAC5B,KAAK,EAAE,QAAQ,EACf,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAAC,gBAAgB,CAAC,CAqCjC"}
|
package/lib/browser/extract.js
CHANGED
|
@@ -9,6 +9,24 @@ import { TarEntryType, } from '../types.js';
|
|
|
9
9
|
/**
|
|
10
10
|
* Parse TAR data into entries
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Handle a PAX_HEADER block: parse its attributes and advance the offset.
|
|
14
|
+
* Returns the updated offset and the parsed PAX attributes.
|
|
15
|
+
*/
|
|
16
|
+
function parsePaxHeaderBlock(data, offset, size) {
|
|
17
|
+
const paxData = data.subarray(offset, offset + size);
|
|
18
|
+
const newOffset = offset + size + calculatePadding(size);
|
|
19
|
+
return { offset: newOffset, paxAttrs: parsePaxData(paxData) };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extract entry content bytes and advance the offset past the content + padding.
|
|
23
|
+
* Returns the updated offset and the content Uint8Array.
|
|
24
|
+
*/
|
|
25
|
+
function extractEntryContent(data, offset, size) {
|
|
26
|
+
const contentData = size > 0 ? data.subarray(offset, offset + size) : new Uint8Array(0);
|
|
27
|
+
const newOffset = offset + size + calculatePadding(size);
|
|
28
|
+
return { offset: newOffset, contentData };
|
|
29
|
+
}
|
|
12
30
|
function parseTar(data) {
|
|
13
31
|
const entries = [];
|
|
14
32
|
let offset = 0;
|
|
@@ -33,10 +51,7 @@ function parseTar(data) {
|
|
|
33
51
|
}
|
|
34
52
|
// Handle PAX headers
|
|
35
53
|
if (entry.type === TarEntryType.PAX_HEADER) {
|
|
36
|
-
|
|
37
|
-
const paxData = data.subarray(offset, offset + paxSize);
|
|
38
|
-
offset += paxSize + calculatePadding(paxSize);
|
|
39
|
-
paxAttrs = parsePaxData(paxData);
|
|
54
|
+
({ offset, paxAttrs } = parsePaxHeaderBlock(data, offset, entry.size));
|
|
40
55
|
continue;
|
|
41
56
|
}
|
|
42
57
|
if (entry.type === TarEntryType.PAX_GLOBAL) {
|
|
@@ -49,8 +64,8 @@ function parseTar(data) {
|
|
|
49
64
|
paxAttrs = null;
|
|
50
65
|
}
|
|
51
66
|
// Extract content
|
|
52
|
-
|
|
53
|
-
offset
|
|
67
|
+
let contentData;
|
|
68
|
+
({ offset, contentData } = extractEntryContent(data, offset, entry.size));
|
|
54
69
|
entries.push({ ...entry, data: contentData });
|
|
55
70
|
}
|
|
56
71
|
return entries;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/browser/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAKL,YAAY,GACb,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,SAAS,QAAQ,CAAC,IAAgB;IAChC,MAAM,OAAO,GAA2C,EAAE,CAAC;IAC3D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAC1C,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,OAAO,MAAM,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC;QAC/D,MAAM,IAAI,UAAU,CAAC;QAErB,2BAA2B;QAC3B,IAAI,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9B,eAAe,EAAE,CAAC;YAClB,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;gBACzB,MAAM;YACR,CAAC;YACD,SAAS;QACX,CAAC;QAED,eAAe,GAAG,CAAC,CAAC;QAEpB,eAAe;QACf,IAAI,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QAED,qBAAqB;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,EAAE,CAAC;YAC3C,
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/browser/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAKL,YAAY,GACb,MAAM,aAAa,CAAC;AAErB;;GAEG;AAEH;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,IAAgB,EAChB,MAAc,EACd,IAAY;IAEZ,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,IAAgB,EAChB,MAAc,EACd,IAAY;IAEZ,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,QAAQ,CAAC,IAAgB;IAChC,MAAM,OAAO,GAA2C,EAAE,CAAC;IAC3D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAC1C,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,OAAO,MAAM,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC;QAC/D,MAAM,IAAI,UAAU,CAAC;QAErB,2BAA2B;QAC3B,IAAI,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9B,eAAe,EAAE,CAAC;YAClB,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;gBACzB,MAAM;YACR,CAAC;YACD,SAAS;QACX,CAAC;QAED,eAAe,GAAG,CAAC,CAAC;QAEpB,eAAe;QACf,IAAI,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QAED,qBAAqB;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,EAAE,CAAC;YAC3C,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACvE,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QAED,kCAAkC;QAClC,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5C,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QAED,kBAAkB;QAClB,IAAI,WAAuB,CAAC;QAC5B,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1E,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,CAC5B,KAAe,EACf,UAA0B,EAAE;IAE5B,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEtC,2BAA2B;IAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5B,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAED,gBAAgB;IAChB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;IAE7C,oBAAoB;IACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QAED,MAAM,aAAa,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QACvD,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;YACrC,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;QAE7B,MAAM,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,SAAS,oBAAoB,CAAC,KAAe,EAAE,IAAgB;IAC7D,KAAK,UAAU,YAAY;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,QAAiB;QAC1C,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,IAAI,WAAW,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO;QACL,GAAG,KAAK;QACR,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;YACpB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,IAAI,CAAC;QAClC,CAAC,CAAC,EAAE;QACJ,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,WAAW;KAClB,CAAC;AACJ,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -10,5 +10,5 @@ export { create, extract, list } from './node/index.js';
|
|
|
10
10
|
export type { TarInputNode } from './node/index.js';
|
|
11
11
|
export type { CreateHeaderOptions, PaxAttributes } from './tar/index.js';
|
|
12
12
|
export { applyPaxAttributes, BLOCK_SIZE, calculatePadding, createEndOfArchive, createHeader, createPaxData, createPaxHeaderBlocks, needsPaxHeaders, parseHeader, parsePaxData, } from './tar/index.js';
|
|
13
|
-
export { type CreateOptions, type ExtractOptions, type TarEntry, TarEntryType, type TarEntryWithData, type TarInput, type TarSourceFile, } from './types.js';
|
|
13
|
+
export { type CreateOptions, type ExtractOptions, type TarEntry, TarEntryType, type TarEntryTypeValue, type TarEntryWithData, type TarInput, type TarSourceFile, } from './types.js';
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGzE,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGzE,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC"}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wBAAwB;AACxB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAIxD,uDAAuD;AACvD,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,kBAAkB;AAClB,OAAO,EAIL,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wBAAwB;AACxB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAIxD,uDAAuD;AACvD,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,kBAAkB;AAClB,OAAO,EAIL,YAAY,GAKb,MAAM,YAAY,CAAC"}
|
package/lib/node/extract.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Node.js TAR extraction with XZ decompression — v6 AsyncIterable API
|
|
3
3
|
*/
|
|
4
4
|
import type { TarInputNode } from '../internal/to-async-iterable.js';
|
|
5
|
-
import {
|
|
5
|
+
import type { ExtractOptions, TarEntryWithData } from '../types.js';
|
|
6
6
|
/**
|
|
7
7
|
* Extract a tar.xz archive.
|
|
8
8
|
*
|
|
@@ -20,7 +20,7 @@ import { type ExtractOptions, type TarEntryWithData } from '../types.js';
|
|
|
20
20
|
* }
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
-
export declare function extract(input: TarInputNode, options?: ExtractOptions):
|
|
23
|
+
export declare function extract(input: TarInputNode, options?: ExtractOptions): AsyncGenerator<TarEntryWithData>;
|
|
24
24
|
/**
|
|
25
25
|
* Extract archive to memory (no disk writes)
|
|
26
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/node/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/node/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAY,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA8P9E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAuB,OAAO,CAC5B,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,cAAmB,GAC3B,cAAc,CAAC,gBAAgB,CAAC,CA4ElC;AAED;;GAEG"}
|