@vibe-agent-toolkit/utils 0.2.0-rc.11 → 0.2.0-rc.12
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/README.md +111 -9
- package/dist/archive/archive.d.ts +129 -0
- package/dist/archive/archive.d.ts.map +1 -0
- package/dist/archive/archive.js +223 -0
- package/dist/archive/archive.js.map +1 -0
- package/dist/archive/entries.d.ts +132 -0
- package/dist/archive/entries.d.ts.map +1 -0
- package/dist/archive/entries.js +223 -0
- package/dist/archive/entries.js.map +1 -0
- package/dist/archive/limits.d.ts +39 -0
- package/dist/archive/limits.d.ts.map +1 -0
- package/dist/archive/limits.js +59 -0
- package/dist/archive/limits.js.map +1 -0
- package/dist/archive/records.d.ts +14 -0
- package/dist/archive/records.d.ts.map +1 -0
- package/dist/archive/records.js +3 -0
- package/dist/archive/records.js.map +1 -0
- package/dist/archive/tar-reader.d.ts +18 -0
- package/dist/archive/tar-reader.d.ts.map +1 -0
- package/dist/archive/tar-reader.js +173 -0
- package/dist/archive/tar-reader.js.map +1 -0
- package/dist/archive/zip-reader.d.ts +76 -0
- package/dist/archive/zip-reader.d.ts.map +1 -0
- package/dist/archive/zip-reader.js +376 -0
- package/dist/archive/zip-reader.js.map +1 -0
- package/dist/archive.d.ts +14 -0
- package/dist/archive.d.ts.map +1 -0
- package/dist/archive.js +12 -0
- package/dist/archive.js.map +1 -0
- package/dist/asset-reference.d.ts +17 -1
- package/dist/asset-reference.d.ts.map +1 -1
- package/dist/asset-reference.js +31 -7
- package/dist/asset-reference.js.map +1 -1
- package/dist/dirent-kind.d.ts +13 -40
- package/dist/dirent-kind.d.ts.map +1 -1
- package/dist/dirent-kind.js +21 -69
- package/dist/dirent-kind.js.map +1 -1
- package/dist/entrypoint.d.ts +2 -2
- package/dist/entrypoint.d.ts.map +1 -1
- package/dist/entrypoint.js +4 -3
- package/dist/entrypoint.js.map +1 -1
- package/dist/env-flag.d.ts +2 -0
- package/dist/env-flag.d.ts.map +1 -1
- package/dist/env-flag.js +2 -0
- package/dist/env-flag.js.map +1 -1
- package/dist/errors/confirmed-absent.d.ts +41 -0
- package/dist/errors/confirmed-absent.d.ts.map +1 -0
- package/dist/errors/confirmed-absent.js +43 -0
- package/dist/errors/confirmed-absent.js.map +1 -0
- package/dist/errors/errno-table.d.ts +177 -0
- package/dist/errors/errno-table.d.ts.map +1 -0
- package/dist/errors/errno-table.js +343 -0
- package/dist/errors/errno-table.js.map +1 -0
- package/dist/errors/fs-boundary.d.ts +36 -0
- package/dist/errors/fs-boundary.d.ts.map +1 -0
- package/dist/errors/fs-boundary.js +121 -0
- package/dist/errors/fs-boundary.js.map +1 -0
- package/dist/errors/fs-fault.d.ts +176 -0
- package/dist/errors/fs-fault.d.ts.map +1 -0
- package/dist/errors/fs-fault.js +215 -0
- package/dist/errors/fs-fault.js.map +1 -0
- package/dist/errors/git-errno.d.ts +13 -0
- package/dist/errors/git-errno.d.ts.map +1 -0
- package/dist/errors/git-errno.js +45 -0
- package/dist/errors/git-errno.js.map +1 -0
- package/dist/errors/path-present.d.ts +72 -0
- package/dist/errors/path-present.d.ts.map +1 -0
- package/dist/errors/path-present.js +110 -0
- package/dist/errors/path-present.js.map +1 -0
- package/dist/errors/rag-index-empty.d.ts +16 -0
- package/dist/errors/rag-index-empty.d.ts.map +1 -0
- package/dist/errors/rag-index-empty.js +16 -0
- package/dist/errors/rag-index-empty.js.map +1 -0
- package/dist/errors/suppressed-faults.d.ts +34 -0
- package/dist/errors/suppressed-faults.d.ts.map +1 -0
- package/dist/errors/suppressed-faults.js +66 -0
- package/dist/errors/suppressed-faults.js.map +1 -0
- package/dist/file-crawler.d.ts +13 -18
- package/dist/file-crawler.d.ts.map +1 -1
- package/dist/file-crawler.js +140 -24
- package/dist/file-crawler.js.map +1 -1
- package/dist/fs-utils.d.ts +75 -50
- package/dist/fs-utils.d.ts.map +1 -1
- package/dist/fs-utils.js +148 -158
- package/dist/fs-utils.js.map +1 -1
- package/dist/fs.d.ts +4 -4
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +4 -4
- package/dist/fs.js.map +1 -1
- package/dist/git-snapshot.d.ts +25 -17
- package/dist/git-snapshot.d.ts.map +1 -1
- package/dist/git-snapshot.js +65 -11
- package/dist/git-snapshot.js.map +1 -1
- package/dist/git-tracker.d.ts +11 -3
- package/dist/git-tracker.d.ts.map +1 -1
- package/dist/git-tracker.js +29 -6
- package/dist/git-tracker.js.map +1 -1
- package/dist/git-utils.d.ts.map +1 -1
- package/dist/git-utils.js +7 -35
- package/dist/git-utils.js.map +1 -1
- package/dist/git.d.ts +1 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +1 -1
- package/dist/git.js.map +1 -1
- package/dist/gitignore-checker.d.ts.map +1 -1
- package/dist/gitignore-checker.js +5 -4
- package/dist/gitignore-checker.js.map +1 -1
- package/dist/in-order.d.ts +93 -0
- package/dist/in-order.d.ts.map +1 -0
- package/dist/in-order.js +165 -0
- package/dist/in-order.js.map +1 -0
- package/dist/index.d.ts +20 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -4
- package/dist/index.js.map +1 -1
- package/dist/kill-process-tree.d.ts +43 -0
- package/dist/kill-process-tree.d.ts.map +1 -0
- package/dist/kill-process-tree.js +48 -0
- package/dist/kill-process-tree.js.map +1 -0
- package/dist/link-following.d.ts +115 -0
- package/dist/link-following.d.ts.map +1 -0
- package/dist/link-following.js +283 -0
- package/dist/link-following.js.map +1 -0
- package/dist/listing-refusal.d.ts +44 -0
- package/dist/listing-refusal.d.ts.map +1 -1
- package/dist/listing-refusal.js +79 -2
- package/dist/listing-refusal.js.map +1 -1
- package/dist/name-fold.d.ts +25 -0
- package/dist/name-fold.d.ts.map +1 -0
- package/dist/name-fold.js +40 -0
- package/dist/name-fold.js.map +1 -0
- package/dist/path-containment.d.ts +3 -1
- package/dist/path-containment.d.ts.map +1 -1
- package/dist/path-containment.js +13 -7
- package/dist/path-containment.js.map +1 -1
- package/dist/path-utils.d.ts +14 -17
- package/dist/path-utils.d.ts.map +1 -1
- package/dist/path-utils.js +37 -55
- package/dist/path-utils.js.map +1 -1
- package/dist/process.d.ts +2 -0
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +2 -0
- package/dist/process.js.map +1 -1
- package/dist/project-utils.d.ts.map +1 -1
- package/dist/project-utils.js +8 -9
- package/dist/project-utils.js.map +1 -1
- package/dist/safe-exec.d.ts +6 -2
- package/dist/safe-exec.d.ts.map +1 -1
- package/dist/safe-exec.js +1 -1
- package/dist/safe-exec.js.map +1 -1
- package/dist/skill-targets.d.ts.map +1 -1
- package/dist/skill-targets.js +3 -1
- package/dist/skill-targets.js.map +1 -1
- package/dist/skill-test/spawn-claude.d.ts +0 -15
- package/dist/skill-test/spawn-claude.d.ts.map +1 -1
- package/dist/skill-test/spawn-claude.js +11 -50
- package/dist/skill-test/spawn-claude.js.map +1 -1
- package/dist/special-file.d.ts +18 -0
- package/dist/special-file.d.ts.map +1 -0
- package/dist/special-file.js +21 -0
- package/dist/special-file.js.map +1 -0
- package/dist/terminating-signals.d.ts +129 -0
- package/dist/terminating-signals.d.ts.map +1 -0
- package/dist/terminating-signals.js +210 -0
- package/dist/terminating-signals.js.map +1 -0
- package/dist/test-helpers.d.ts +9 -5
- package/dist/test-helpers.d.ts.map +1 -1
- package/dist/test-helpers.js +18 -21
- package/dist/test-helpers.js.map +1 -1
- package/dist/test-scratch-guard.d.ts +34 -0
- package/dist/test-scratch-guard.d.ts.map +1 -0
- package/dist/test-scratch-guard.js +45 -0
- package/dist/test-scratch-guard.js.map +1 -0
- package/dist/testing/archive-fixtures.d.ts +147 -0
- package/dist/testing/archive-fixtures.d.ts.map +1 -0
- package/dist/testing/archive-fixtures.js +449 -0
- package/dist/testing/archive-fixtures.js.map +1 -0
- package/dist/testing/executables.d.ts +6 -0
- package/dist/testing/executables.d.ts.map +1 -1
- package/dist/testing/executables.js +20 -9
- package/dist/testing/executables.js.map +1 -1
- package/dist/testing/fault-fs-preload.d.ts +16 -0
- package/dist/testing/fault-fs-preload.d.ts.map +1 -0
- package/dist/testing/fault-fs-preload.js +22 -0
- package/dist/testing/fault-fs-preload.js.map +1 -0
- package/dist/testing/fault-fs.d.ts +115 -0
- package/dist/testing/fault-fs.d.ts.map +1 -0
- package/dist/testing/fault-fs.js +411 -0
- package/dist/testing/fault-fs.js.map +1 -0
- package/dist/testing/fault-spec.d.ts +83 -0
- package/dist/testing/fault-spec.d.ts.map +1 -0
- package/dist/testing/fault-spec.js +132 -0
- package/dist/testing/fault-spec.js.map +1 -0
- package/dist/testing/hostile-tree.d.ts.map +1 -1
- package/dist/testing/hostile-tree.js +3 -4
- package/dist/testing/hostile-tree.js.map +1 -1
- package/dist/testing/platform-gates.d.ts +8 -0
- package/dist/testing/platform-gates.d.ts.map +1 -1
- package/dist/testing/platform-gates.js +24 -0
- package/dist/testing/platform-gates.js.map +1 -1
- package/dist/testing/temp-dir.d.ts +31 -0
- package/dist/testing/temp-dir.d.ts.map +1 -1
- package/dist/testing/temp-dir.js +63 -0
- package/dist/testing/temp-dir.js.map +1 -1
- package/dist/testing/tier-timeout.d.ts +34 -0
- package/dist/testing/tier-timeout.d.ts.map +1 -0
- package/dist/testing/tier-timeout.js +45 -0
- package/dist/testing/tier-timeout.js.map +1 -0
- package/dist/testing/tree-snapshot.d.ts +71 -0
- package/dist/testing/tree-snapshot.d.ts.map +1 -0
- package/dist/testing/tree-snapshot.js +163 -0
- package/dist/testing/tree-snapshot.js.map +1 -0
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +8 -1
- package/dist/testing.js.map +1 -1
- package/dist/text-file.d.ts +14 -1
- package/dist/text-file.d.ts.map +1 -1
- package/dist/text-file.js +41 -8
- package/dist/text-file.js.map +1 -1
- package/dist/timing-dump.d.ts.map +1 -1
- package/dist/timing-dump.js +2 -10
- package/dist/timing-dump.js.map +1 -1
- package/dist/tree-change/apply-decisions.d.ts +101 -0
- package/dist/tree-change/apply-decisions.d.ts.map +1 -0
- package/dist/tree-change/apply-decisions.js +139 -0
- package/dist/tree-change/apply-decisions.js.map +1 -0
- package/dist/tree-change/apply.d.ts +98 -0
- package/dist/tree-change/apply.d.ts.map +1 -0
- package/dist/tree-change/apply.js +364 -0
- package/dist/tree-change/apply.js.map +1 -0
- package/dist/tree-change/copy-decisions.d.ts +58 -0
- package/dist/tree-change/copy-decisions.d.ts.map +1 -0
- package/dist/tree-change/copy-decisions.js +66 -0
- package/dist/tree-change/copy-decisions.js.map +1 -0
- package/dist/tree-change/copy-tree.d.ts +125 -0
- package/dist/tree-change/copy-tree.d.ts.map +1 -0
- package/dist/tree-change/copy-tree.js +279 -0
- package/dist/tree-change/copy-tree.js.map +1 -0
- package/dist/tree-change/files.d.ts +167 -0
- package/dist/tree-change/files.d.ts.map +1 -0
- package/dist/tree-change/files.js +423 -0
- package/dist/tree-change/files.js.map +1 -0
- package/dist/tree-change/followed-walk.d.ts +54 -0
- package/dist/tree-change/followed-walk.d.ts.map +1 -0
- package/dist/tree-change/followed-walk.js +81 -0
- package/dist/tree-change/followed-walk.js.map +1 -0
- package/dist/tree-change/host-chain.d.ts +48 -0
- package/dist/tree-change/host-chain.d.ts.map +1 -0
- package/dist/tree-change/host-chain.js +85 -0
- package/dist/tree-change/host-chain.js.map +1 -0
- package/dist/tree-change/identity-compare.d.ts +61 -0
- package/dist/tree-change/identity-compare.d.ts.map +1 -0
- package/dist/tree-change/identity-compare.js +115 -0
- package/dist/tree-change/identity-compare.js.map +1 -0
- package/dist/tree-change/identity.d.ts +62 -0
- package/dist/tree-change/identity.d.ts.map +1 -0
- package/dist/tree-change/identity.js +152 -0
- package/dist/tree-change/identity.js.map +1 -0
- package/dist/tree-change/index.d.ts +24 -0
- package/dist/tree-change/index.d.ts.map +1 -0
- package/dist/tree-change/index.js +14 -0
- package/dist/tree-change/index.js.map +1 -0
- package/dist/tree-change/link-chain.d.ts +180 -0
- package/dist/tree-change/link-chain.d.ts.map +1 -0
- package/dist/tree-change/link-chain.js +377 -0
- package/dist/tree-change/link-chain.js.map +1 -0
- package/dist/tree-change/link-containment.d.ts +105 -0
- package/dist/tree-change/link-containment.d.ts.map +1 -0
- package/dist/tree-change/link-containment.js +196 -0
- package/dist/tree-change/link-containment.js.map +1 -0
- package/dist/tree-change/link-walk.d.ts +49 -0
- package/dist/tree-change/link-walk.d.ts.map +1 -0
- package/dist/tree-change/link-walk.js +69 -0
- package/dist/tree-change/link-walk.js.map +1 -0
- package/dist/tree-change/plan.d.ts +206 -0
- package/dist/tree-change/plan.d.ts.map +1 -0
- package/dist/tree-change/plan.js +320 -0
- package/dist/tree-change/plan.js.map +1 -0
- package/dist/tree-change/readable-tree.d.ts +44 -0
- package/dist/tree-change/readable-tree.d.ts.map +1 -0
- package/dist/tree-change/readable-tree.js +52 -0
- package/dist/tree-change/readable-tree.js.map +1 -0
- package/dist/tree-change/rollback-error.d.ts +29 -0
- package/dist/tree-change/rollback-error.d.ts.map +1 -0
- package/dist/tree-change/rollback-error.js +31 -0
- package/dist/tree-change/rollback-error.js.map +1 -0
- package/dist/tree-change/staging-names.d.ts +27 -0
- package/dist/tree-change/staging-names.d.ts.map +1 -0
- package/dist/tree-change/staging-names.js +40 -0
- package/dist/tree-change/staging-names.js.map +1 -0
- package/dist/tree-change/tree-walk.d.ts +81 -0
- package/dist/tree-change/tree-walk.d.ts.map +1 -0
- package/dist/tree-change/tree-walk.js +212 -0
- package/dist/tree-change/tree-walk.js.map +1 -0
- package/dist/win32-namespace.d.ts +24 -0
- package/dist/win32-namespace.d.ts.map +1 -0
- package/dist/win32-namespace.js +31 -0
- package/dist/win32-namespace.js.map +1 -0
- package/dist/yaml/surgical-yaml.d.ts +12 -3
- package/dist/yaml/surgical-yaml.d.ts.map +1 -1
- package/dist/yaml/surgical-yaml.js +16 -6
- package/dist/yaml/surgical-yaml.js.map +1 -1
- package/eslint/README.md +12 -4
- package/eslint/rules/fs-binding-scan.cjs +278 -0
- package/eslint/rules/no-adhoc-errno.cjs +364 -0
- package/eslint/rules/no-bare-symlink-in-tests.cjs +2 -3
- package/eslint/rules/no-blind-catch.cjs +1 -1
- package/eslint/rules/no-destructive-fs.cjs +359 -0
- package/eslint/rules/no-existssync.cjs +70 -0
- package/eslint/rules/no-fragile-entrypoint-guard.cjs +3 -2
- package/eslint/rules/no-link-following-fs.cjs +68 -0
- package/eslint/rules/no-literal-process-exit.cjs +3 -16
- package/eslint/rules/no-literal-test-timeout.cjs +214 -0
- package/eslint/rules/no-raw-signal-listener.cjs +224 -0
- package/eslint/rules/no-stdout-outside-writer.cjs +135 -0
- package/package.json +10 -2
- package/dist/errors/errno.d.ts +0 -51
- package/dist/errors/errno.d.ts.map +0 -1
- package/dist/errors/errno.js +0 -112
- package/dist/errors/errno.js.map +0 -1
- package/eslint/rules/no-fs-promises-cp.cjs +0 -43
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archives for tests, written byte by byte — the ONE place a suite builds a tarball or a ZIP.
|
|
3
|
+
*
|
|
4
|
+
* Hand-written on purpose. An archive library writes only what it considers an archive: it
|
|
5
|
+
* strips a leading `/`, folds `..` away, refuses a name listed twice and will not mark an entry
|
|
6
|
+
* a link or a device. Those are exactly the archives an extractor must refuse, so a fixture
|
|
7
|
+
* built with the library under test cannot express them. Nothing here imports `tar` or
|
|
8
|
+
* `adm-zip` — only `packages/utils/src/archive/` does.
|
|
9
|
+
*/
|
|
10
|
+
import { readdirSync, readFileSync, readlinkSync, statSync } from 'node:fs';
|
|
11
|
+
import { crc32, deflateRawSync, gzipSync } from 'node:zlib';
|
|
12
|
+
import { safePath } from '../path-core.js';
|
|
13
|
+
/**
|
|
14
|
+
* One PAX extended-header record, `<length> <key>=<value>\n`, the length counting itself: the
|
|
15
|
+
* `data` of a `tarType: 'x'` entry, which overrides that field of the entry after it.
|
|
16
|
+
*
|
|
17
|
+
* @param key - The field: `path`, `linkpath`, `size`
|
|
18
|
+
* @param value - Its value, verbatim
|
|
19
|
+
*/
|
|
20
|
+
export function paxRecord(key, value) {
|
|
21
|
+
const body = ` ${key}=${value}\n`;
|
|
22
|
+
let length = Buffer.byteLength(body) + 1;
|
|
23
|
+
while (Buffer.byteLength(`${length}${body}`) !== length)
|
|
24
|
+
length += 1;
|
|
25
|
+
return `${length}${body}`;
|
|
26
|
+
}
|
|
27
|
+
const BLOCK = 512;
|
|
28
|
+
/** The tar type flag of each entry kind. */
|
|
29
|
+
const TAR_TYPE = {
|
|
30
|
+
file: '0',
|
|
31
|
+
hardlink: '1',
|
|
32
|
+
link: '2',
|
|
33
|
+
device: '3',
|
|
34
|
+
directory: '5',
|
|
35
|
+
fifo: '6',
|
|
36
|
+
};
|
|
37
|
+
/** The file-type bits of a Unix mode, as a ZIP made on Unix keeps them in an entry's external attributes. */
|
|
38
|
+
const ZIP_TYPE_BITS = {
|
|
39
|
+
file: 0o100000,
|
|
40
|
+
link: 0o120000,
|
|
41
|
+
device: 0o020000,
|
|
42
|
+
directory: 0o040000,
|
|
43
|
+
fifo: 0o010000,
|
|
44
|
+
};
|
|
45
|
+
const bytesOf = (data) => Buffer.from(data ?? '');
|
|
46
|
+
const permissionsOf = (entry) => entry.mode ?? (entry.kind === 'directory' ? 0o755 : 0o644);
|
|
47
|
+
/** An octal header field: `width - 1` digits and a NUL. */
|
|
48
|
+
const octal = (value, width) => `${value.toString(8).padStart(width - 1, '0')}\0`;
|
|
49
|
+
/**
|
|
50
|
+
* Where a tar name is cut between the header's `prefix` (155 bytes) and `name` (100 bytes) fields.
|
|
51
|
+
*
|
|
52
|
+
* @throws When the name fits neither way: a fixture needing a longer name needs a PAX header, which this does not write
|
|
53
|
+
*/
|
|
54
|
+
function splitTarName(name) {
|
|
55
|
+
if (Buffer.byteLength(name) <= 100)
|
|
56
|
+
return { prefix: '', name };
|
|
57
|
+
for (let cut = name.indexOf('/'); cut !== -1; cut = name.indexOf('/', cut + 1)) {
|
|
58
|
+
const prefix = name.slice(0, cut);
|
|
59
|
+
const rest = name.slice(cut + 1);
|
|
60
|
+
if (Buffer.byteLength(prefix) <= 155 && Buffer.byteLength(rest) <= 100 && rest !== '')
|
|
61
|
+
return { prefix, name: rest };
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`tarFixture: the entry name does not fit a ustar header: ${name}`);
|
|
64
|
+
}
|
|
65
|
+
/** One ustar header block. */
|
|
66
|
+
function tarHeader(entry, size) {
|
|
67
|
+
const block = Buffer.alloc(BLOCK);
|
|
68
|
+
const { prefix, name } = splitTarName(entry.name);
|
|
69
|
+
block.write(name, 0, 100, 'utf8');
|
|
70
|
+
block.write(octal(permissionsOf(entry), 8), 100, 8, 'latin1');
|
|
71
|
+
block.write(octal(0, 8), 108, 8, 'latin1');
|
|
72
|
+
block.write(octal(0, 8), 116, 8, 'latin1');
|
|
73
|
+
block.write(octal(size, 12), 124, 12, 'latin1');
|
|
74
|
+
block.write(octal(0, 12), 136, 12, 'latin1');
|
|
75
|
+
// The checksum is summed with its own field as spaces.
|
|
76
|
+
block.fill(' ', 148, 156);
|
|
77
|
+
block.write(entry.tarType ?? TAR_TYPE[entry.kind ?? 'file'], 156, 1, 'latin1');
|
|
78
|
+
block.write(entry.target ?? '', 157, 100, 'utf8');
|
|
79
|
+
block.write('ustar\0' + '00', 257, 8, 'latin1');
|
|
80
|
+
block.write(prefix, 345, 155, 'utf8');
|
|
81
|
+
let sum = 0;
|
|
82
|
+
for (const byte of block)
|
|
83
|
+
sum += byte;
|
|
84
|
+
block.write(`${sum.toString(8).padStart(6, '0')}\0 `, 148, 8, 'latin1');
|
|
85
|
+
return block;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* A tar archive of `entries`, in order, gzipped unless `options.gzip` is `false`.
|
|
89
|
+
*
|
|
90
|
+
* @param entries - The entries, written exactly as given
|
|
91
|
+
* @param options - `gzip: false` for a plain tar
|
|
92
|
+
* @returns The archive's bytes
|
|
93
|
+
*/
|
|
94
|
+
export function tarFixture(entries, options = {}) {
|
|
95
|
+
const blocks = [];
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
const data = bytesOf(entry.data);
|
|
98
|
+
blocks.push(tarHeader(entry, entry.declaredSize ?? data.length), data, Buffer.alloc((BLOCK - (data.length % BLOCK)) % BLOCK));
|
|
99
|
+
}
|
|
100
|
+
// Two empty blocks end a tar archive.
|
|
101
|
+
const plain = Buffer.concat([...blocks, Buffer.alloc(2 * BLOCK)]);
|
|
102
|
+
return options.gzip === false ? plain : gzipSync(plain);
|
|
103
|
+
}
|
|
104
|
+
/** The `version made by` of a ZIP entry: host 3 (Unix), so a reader takes the external attributes for a Unix mode. */
|
|
105
|
+
const ZIP_MADE_BY_UNIX = (3 << 8) | 20;
|
|
106
|
+
/** General-purpose bit 11: the entry name is UTF-8. */
|
|
107
|
+
const ZIP_UTF8_NAMES = 0x0800;
|
|
108
|
+
/** A date as a ZIP header's two 16-bit fields, time then date, packed as the one 32-bit value they are stored as. */
|
|
109
|
+
function dosTimestamp(at) {
|
|
110
|
+
if (at === undefined)
|
|
111
|
+
return 0;
|
|
112
|
+
const time = (at.getHours() << 11) | (at.getMinutes() << 5) | (at.getSeconds() >> 1);
|
|
113
|
+
const date = ((at.getFullYear() - 1980) << 9) | ((at.getMonth() + 1) << 5) | at.getDate();
|
|
114
|
+
return ((date << 16) | time) >>> 0;
|
|
115
|
+
}
|
|
116
|
+
/** The bytes a ZIP entry stores, and how: a link stores its target, a file its (deflated) data. */
|
|
117
|
+
function zipPayload(entry, compress) {
|
|
118
|
+
if (entry.kind === 'hardlink')
|
|
119
|
+
throw new Error('zipFixture: a ZIP has no hard-link entry');
|
|
120
|
+
const raw = entry.kind === 'link' ? Buffer.from(entry.target ?? '') : bytesOf(entry.data);
|
|
121
|
+
const deflate = compress && raw.length > 0;
|
|
122
|
+
return { stored: deflate ? deflateRawSync(raw) : raw, raw, method: deflate ? 8 : 0 };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A ZIP archive of `entries`, in order, each as a ZIP made on Unix records it (so a link, a
|
|
126
|
+
* device and an executable bit are all expressible).
|
|
127
|
+
*
|
|
128
|
+
* @param entries - The entries, written exactly as given; a `hardlink` throws (a ZIP has none)
|
|
129
|
+
* @param options - `compress: false` to store every entry instead of deflating it
|
|
130
|
+
* @returns The archive's bytes
|
|
131
|
+
*/
|
|
132
|
+
export function zipFixture(entries, options = {}) {
|
|
133
|
+
const locals = [];
|
|
134
|
+
const centrals = [];
|
|
135
|
+
let offset = 0;
|
|
136
|
+
for (const entry of entries) {
|
|
137
|
+
const kind = entry.kind ?? 'file';
|
|
138
|
+
const { stored, raw, method } = zipPayload(entry, options.compress !== false);
|
|
139
|
+
const name = Buffer.from(entry.name, 'utf8');
|
|
140
|
+
const size = entry.declaredSize ?? raw.length;
|
|
141
|
+
const checksum = crc32(raw);
|
|
142
|
+
const local = Buffer.alloc(30);
|
|
143
|
+
local.writeUInt32LE(0x04034b50, 0);
|
|
144
|
+
local.writeUInt16LE(20, 4);
|
|
145
|
+
local.writeUInt16LE(ZIP_UTF8_NAMES, 6);
|
|
146
|
+
local.writeUInt16LE(method, 8);
|
|
147
|
+
local.writeUInt32LE(dosTimestamp(entry.modified), 10);
|
|
148
|
+
local.writeUInt32LE(checksum, 14);
|
|
149
|
+
local.writeUInt32LE(stored.length, 18);
|
|
150
|
+
local.writeUInt32LE(size, 22);
|
|
151
|
+
local.writeUInt16LE(name.length, 26);
|
|
152
|
+
const central = Buffer.alloc(46);
|
|
153
|
+
central.writeUInt32LE(0x02014b50, 0);
|
|
154
|
+
central.writeUInt16LE(ZIP_MADE_BY_UNIX, 4);
|
|
155
|
+
central.writeUInt16LE(20, 6);
|
|
156
|
+
central.writeUInt16LE(ZIP_UTF8_NAMES, 8);
|
|
157
|
+
central.writeUInt16LE(method, 10);
|
|
158
|
+
central.writeUInt32LE(dosTimestamp(entry.modified), 12);
|
|
159
|
+
central.writeUInt32LE(checksum, 16);
|
|
160
|
+
central.writeUInt32LE(stored.length, 20);
|
|
161
|
+
central.writeUInt32LE(size, 24);
|
|
162
|
+
central.writeUInt16LE(name.length, 28);
|
|
163
|
+
central.writeUInt32LE((((kind === 'hardlink' ? 0 : ZIP_TYPE_BITS[kind]) | permissionsOf(entry)) << 16) >>> 0, 38);
|
|
164
|
+
central.writeUInt32LE(offset, 42);
|
|
165
|
+
locals.push(local, name, stored);
|
|
166
|
+
centrals.push(central, name);
|
|
167
|
+
offset += local.length + name.length + stored.length;
|
|
168
|
+
}
|
|
169
|
+
const directory = Buffer.concat(centrals);
|
|
170
|
+
const end = Buffer.alloc(22);
|
|
171
|
+
end.writeUInt32LE(0x06054b50, 0);
|
|
172
|
+
end.writeUInt16LE(entries.length, 8);
|
|
173
|
+
end.writeUInt16LE(entries.length, 10);
|
|
174
|
+
end.writeUInt32LE(directory.length, 12);
|
|
175
|
+
end.writeUInt32LE(offset, 16);
|
|
176
|
+
return Buffer.concat([...locals, directory, end]);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* A directory tree as fixture entries, in listing order: each directory, then what it holds; a
|
|
180
|
+
* file with its bytes and permission bits; a symbolic link as a link entry with its target
|
|
181
|
+
* verbatim (never followed). What a test that used to `tar` or `zip` a directory hands
|
|
182
|
+
* {@link tarFixture} or {@link zipFixture}.
|
|
183
|
+
*
|
|
184
|
+
* @param dir - The directory to read
|
|
185
|
+
* @param prefix - What each entry name begins with: `''`, or a directory name ending in `/` (`package/`)
|
|
186
|
+
* @returns The entries of `dir`, `dir` itself not among them
|
|
187
|
+
*/
|
|
188
|
+
export function archiveEntriesOfDirectory(dir, prefix = '') {
|
|
189
|
+
const entries = [];
|
|
190
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
191
|
+
const path = safePath.join(dir, entry.name);
|
|
192
|
+
const name = `${prefix}${entry.name}`;
|
|
193
|
+
if (entry.isSymbolicLink()) {
|
|
194
|
+
entries.push({ name, kind: 'link', target: readlinkSync(path) });
|
|
195
|
+
}
|
|
196
|
+
else if (entry.isDirectory()) {
|
|
197
|
+
entries.push({ name: `${name}/`, kind: 'directory' }, ...archiveEntriesOfDirectory(path, `${name}/`));
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
entries.push({ name, data: readFileSync(path), mode: statSync(path).mode & 0o777 });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return entries;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* An archive of `format` holding `entries` — {@link tarFixture} (gzipped) or {@link zipFixture}
|
|
207
|
+
* (deflated) — for a suite that runs the same rows through both formats.
|
|
208
|
+
*/
|
|
209
|
+
export function archiveFixture(format, entries) {
|
|
210
|
+
return format === 'tar' ? tarFixture(entries) : zipFixture(entries);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* The archive a row stands for: `built` — the suite's sound archive with the row's entries — as
|
|
214
|
+
* the row frames it. Every suite that runs {@link hostileArchiveRows} passes its bytes through here.
|
|
215
|
+
*
|
|
216
|
+
* @param row - The row
|
|
217
|
+
* @param built - The archive the suite built from the row's entries
|
|
218
|
+
*/
|
|
219
|
+
export function hostileArchive(row, built) {
|
|
220
|
+
return row.mangle === undefined ? built : row.mangle(built);
|
|
221
|
+
}
|
|
222
|
+
/** A ZIP's end-of-central-directory record: its size, and where {@link zipFixture} — which writes no comment — keeps it. */
|
|
223
|
+
const ZIP_END_SIZE = 22;
|
|
224
|
+
const zipEndOf = (archive) => archive.length - ZIP_END_SIZE;
|
|
225
|
+
/** A four-byte little-endian signature, then zeros up to `length`. */
|
|
226
|
+
function signed(signature, length) {
|
|
227
|
+
const record = Buffer.alloc(length);
|
|
228
|
+
record.writeUInt32LE(signature, 0);
|
|
229
|
+
return record;
|
|
230
|
+
}
|
|
231
|
+
/** `archive` (a {@link zipFixture}) with `comment` as its archive comment, the end record declaring its length. */
|
|
232
|
+
function withZipComment(archive, comment) {
|
|
233
|
+
const commented = Buffer.concat([archive, comment]);
|
|
234
|
+
commented.writeUInt16LE(comment.length, zipEndOf(archive) + 20);
|
|
235
|
+
return commented;
|
|
236
|
+
}
|
|
237
|
+
/** `archive` (a {@link zipFixture}) with its end record's two entry counts made to differ. */
|
|
238
|
+
function withTwoCounts(archive) {
|
|
239
|
+
const counted = Buffer.from(archive);
|
|
240
|
+
counted.writeUInt16LE(counted.readUInt16LE(zipEndOf(counted) + 10) + 1, zipEndOf(counted) + 10);
|
|
241
|
+
return counted;
|
|
242
|
+
}
|
|
243
|
+
/** Where a ZIP's central directory begins, as the end record of a {@link zipFixture} names it. */
|
|
244
|
+
const zipDirectoryOf = (archive) => archive.readUInt32LE(zipEndOf(archive) + 16);
|
|
245
|
+
/**
|
|
246
|
+
* `archive` (a {@link zipFixture}) with `stub` before its first local header: a self-extracting
|
|
247
|
+
* ZIP. `adjusted` moves every offset its central directory and end record hold by the stub's
|
|
248
|
+
* length, as `zip -A` and an SFX builder do, so the directory still names each local header.
|
|
249
|
+
*
|
|
250
|
+
* @param archive - The ZIP
|
|
251
|
+
* @param stub - The bytes to put before it
|
|
252
|
+
* @param adjusted - Whether the offsets are moved to match
|
|
253
|
+
*/
|
|
254
|
+
export function withZipStub(archive, stub, adjusted) {
|
|
255
|
+
const out = Buffer.concat([stub, archive]);
|
|
256
|
+
if (!adjusted)
|
|
257
|
+
return out;
|
|
258
|
+
const end = zipEndOf(out);
|
|
259
|
+
const directory = zipDirectoryOf(archive);
|
|
260
|
+
let at = stub.length + directory;
|
|
261
|
+
for (let index = 0; index < out.readUInt16LE(end + 8); index++) {
|
|
262
|
+
out.writeUInt32LE(out.readUInt32LE(at + 42) + stub.length, at + 42);
|
|
263
|
+
at += 46 + out.readUInt16LE(at + 28) + out.readUInt16LE(at + 30) + out.readUInt16LE(at + 32);
|
|
264
|
+
}
|
|
265
|
+
out.writeUInt32LE(directory + stub.length, end + 16);
|
|
266
|
+
return out;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* `archive` (a {@link zipFixture}) carrying `entry` as a local header and its data after its last
|
|
270
|
+
* listed entry, before a central directory that does not list it: an entry only a reader that
|
|
271
|
+
* walks local headers from the front sees. Every offset still agrees, so a reader that holds the
|
|
272
|
+
* directory to its own reading takes the archive.
|
|
273
|
+
*
|
|
274
|
+
* @param archive - The ZIP
|
|
275
|
+
* @param entry - The entry its local headers hold and its directory does not
|
|
276
|
+
*/
|
|
277
|
+
export function withUnlistedLocalEntry(archive, entry) {
|
|
278
|
+
const lone = zipFixture([entry]);
|
|
279
|
+
const local = lone.subarray(0, zipDirectoryOf(lone));
|
|
280
|
+
const directory = zipDirectoryOf(archive);
|
|
281
|
+
const out = Buffer.concat([archive.subarray(0, directory), local, archive.subarray(directory)]);
|
|
282
|
+
out.writeUInt32LE(directory + local.length, zipEndOf(out) + 16);
|
|
283
|
+
return out;
|
|
284
|
+
}
|
|
285
|
+
const PLANTED_DIRECTORY = 'planted/';
|
|
286
|
+
/**
|
|
287
|
+
* `archive` (a {@link zipFixture}) with one more central record, listed first: a directory,
|
|
288
|
+
* `planted/`, whose local header the record says is at `offset`. Nothing checks a directory's local
|
|
289
|
+
* header when the entry is read — a directory has no data — so the record can name any bytes.
|
|
290
|
+
*
|
|
291
|
+
* @param archive - The ZIP
|
|
292
|
+
* @param offset - Where the record says its local header is
|
|
293
|
+
*/
|
|
294
|
+
function withDirectoryRecordAt(archive, offset) {
|
|
295
|
+
const name = Buffer.from(PLANTED_DIRECTORY, 'utf8');
|
|
296
|
+
const record = Buffer.alloc(46);
|
|
297
|
+
record.writeUInt32LE(0x02014b50, 0);
|
|
298
|
+
record.writeUInt16LE(ZIP_MADE_BY_UNIX, 4);
|
|
299
|
+
record.writeUInt16LE(20, 6);
|
|
300
|
+
record.writeUInt16LE(ZIP_UTF8_NAMES, 8);
|
|
301
|
+
record.writeUInt16LE(name.length, 28);
|
|
302
|
+
record.writeUInt32LE(((ZIP_TYPE_BITS.directory | 0o755) << 16) >>> 0, 38);
|
|
303
|
+
record.writeUInt32LE(offset, 42);
|
|
304
|
+
const directory = zipDirectoryOf(archive);
|
|
305
|
+
const out = Buffer.concat([archive.subarray(0, directory), record, name, archive.subarray(directory)]);
|
|
306
|
+
const end = zipEndOf(out);
|
|
307
|
+
out.writeUInt16LE(out.readUInt16LE(end + 8) + 1, end + 8);
|
|
308
|
+
out.writeUInt16LE(out.readUInt16LE(end + 10) + 1, end + 10);
|
|
309
|
+
out.writeUInt32LE(out.readUInt32LE(end + 12) + record.length + name.length, end + 12);
|
|
310
|
+
return out;
|
|
311
|
+
}
|
|
312
|
+
/** What a self-extracting ZIP carries before its first local header: an executable's first bytes. */
|
|
313
|
+
const SFX_STUB = Buffer.from('MZ self-extracting stub, standing in for an executable');
|
|
314
|
+
/** A stub that is itself a local header and its data: an entry a reader walking from the front takes, and no directory lists. */
|
|
315
|
+
const localHeaderStub = () => {
|
|
316
|
+
const lone = zipFixture([{ name: 'evals/planted.md', data: 'planted' }]);
|
|
317
|
+
return lone.subarray(0, zipDirectoryOf(lone));
|
|
318
|
+
};
|
|
319
|
+
/** The signatures a ZIP reader scans for: the end record, the ZIP64 end record, and the ZIP64 locator. */
|
|
320
|
+
const ZIP_END = 0x06054b50;
|
|
321
|
+
const ZIP64_END = 0x06064b50;
|
|
322
|
+
const ZIP64_LOCATOR = 0x07064b50;
|
|
323
|
+
/**
|
|
324
|
+
* A ZIP that is sound in every entry and hostile in its FRAME: built so that two readers find two
|
|
325
|
+
* different central directories, or so that the count VAT bounds is not the count a library
|
|
326
|
+
* builds. Each is a ZIP VAT parsed and will not take (`unsupported`) — refused in every lane,
|
|
327
|
+
* the one that passes `unreadable` bytes on included.
|
|
328
|
+
*/
|
|
329
|
+
const ZIP_FRAMINGS = [
|
|
330
|
+
['a ZIP64 locator before its end record', (archive) => Buffer.concat([archive.subarray(0, zipEndOf(archive)), signed(ZIP64_LOCATOR, 20), archive.subarray(zipEndOf(archive))])],
|
|
331
|
+
['a ZIP64 record in its comment', (archive) => withZipComment(archive, signed(ZIP64_END, 56))],
|
|
332
|
+
['a second end record in its comment', (archive) => withZipComment(archive, signed(ZIP_END, ZIP_END_SIZE))],
|
|
333
|
+
['an end record that counts its entries two ways', withTwoCounts],
|
|
334
|
+
['bytes after its end record', (archive) => Buffer.concat([archive, Buffer.from('trailing bytes')])],
|
|
335
|
+
// Data before the first local header is refused whether or not the offsets were moved for it.
|
|
336
|
+
['a self-extracting stub, its offsets not adjusted', (archive) => withZipStub(archive, SFX_STUB, false)],
|
|
337
|
+
['a self-extracting stub, its offsets adjusted', (archive) => withZipStub(archive, SFX_STUB, true)],
|
|
338
|
+
['an unlisted local entry before its first listed one, its offsets adjusted', (archive) => withZipStub(archive, localHeaderStub(), true)],
|
|
339
|
+
// A record naming offset 0 is not a local header AT offset 0: a directory's header is never read.
|
|
340
|
+
['an unlisted local entry at offset 0, under a directory record that names it', (archive) => withDirectoryRecordAt(withZipStub(archive, localHeaderStub(), true), 0)],
|
|
341
|
+
['a directory record naming bytes that are no local header', (archive) => withDirectoryRecordAt(archive, 1)],
|
|
342
|
+
];
|
|
343
|
+
const ZIP_FRAMING_ROWS = ZIP_FRAMINGS.map(([what, mangle]) => ({ what, formats: ['zip'], reason: 'unsupported', entries: () => [], mangle }));
|
|
344
|
+
/** One byte more than a reader's end-record search window (the record, plus the longest comment it may declare) holds after the record. */
|
|
345
|
+
const PAST_END_RECORD_WINDOW = 0x1_00_00;
|
|
346
|
+
/** `archive` with zeros appended past the window, so a reader searching back from the end finds no end record — and the bytes are still a ZIP. */
|
|
347
|
+
const padPastEndRecordWindow = (archive) => Buffer.concat([archive, Buffer.alloc(PAST_END_RECORD_WINDOW)]);
|
|
348
|
+
/** A ZIP whose end record lies beyond the search window: still a ZIP (`unsupported`), never bytes that are none (`unreadable`) — refused whether its entries are hostile or sound. */
|
|
349
|
+
const ZIP_PADDED_ROWS = [
|
|
350
|
+
{ what: 'a symbolic link, padded past the end-record search window', formats: ['zip'], reason: 'unsupported', entries: (prefix) => [{ name: `${prefix}keys`, kind: 'link', target: 'SKILL.md' }], mangle: padPastEndRecordWindow },
|
|
351
|
+
{ what: 'nothing hostile, padded past the end-record search window', formats: ['zip'], reason: 'unsupported', entries: () => [], mangle: padPastEndRecordWindow },
|
|
352
|
+
];
|
|
353
|
+
const BOTH = ['tar', 'zip'];
|
|
354
|
+
/** The two reasons most rows share. */
|
|
355
|
+
const UNSAFE_NAME = 'unsafe-name';
|
|
356
|
+
const NAME_CLASH = 'name-clash';
|
|
357
|
+
/** `e` with an acute accent, precomposed and as `e` + a combining accent: one name on a normalising volume. */
|
|
358
|
+
const E_ACUTE_COMPOSED = String.fromCodePoint(0xe9);
|
|
359
|
+
const E_ACUTE_DECOMPOSED = `e${String.fromCodePoint(0x301)}`;
|
|
360
|
+
/**
|
|
361
|
+
* A ZIP member that holds more than its directory declares: the archive parses and its entry list
|
|
362
|
+
* passes the policy, and the member is refused only when it is READ — `ArchiveEntryReadError`,
|
|
363
|
+
* `ARCHIVE_ENTRY_UNREADABLE`, never an `ArchiveRefusedError`, so it is no row of
|
|
364
|
+
* {@link hostileArchiveRows} (whose rows each name an `ArchiveRefusedError` reason). Each lane that
|
|
365
|
+
* reads a ZIP's members runs it beside that table, so the CLI's mapping of the code to
|
|
366
|
+
* `INPUT_UNREADABLE` is held by every lane that can raise it.
|
|
367
|
+
*
|
|
368
|
+
* @param prefix - Where inside the archive it goes: `''`, or a directory name ending in `/`
|
|
369
|
+
*/
|
|
370
|
+
export function entryHoldingMoreThanDeclared(prefix) {
|
|
371
|
+
return [{ name: `${prefix}guide.md`, data: 'this member holds more than it declares', declaredSize: 3 }];
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Every shape of archive VAT refuses to extract, as rows a suite runs through each lane that
|
|
375
|
+
* extracts one: the same table for the archive module's own tests and for every verb's.
|
|
376
|
+
*
|
|
377
|
+
* @param limits - The bounds the lane under test holds an archive to; the last two rows are built just past them
|
|
378
|
+
*/
|
|
379
|
+
export function hostileArchiveRows(limits) {
|
|
380
|
+
return [
|
|
381
|
+
{ what: 'a symbolic link', formats: BOTH, reason: 'link', entries: (prefix) => [{ name: `${prefix}keys`, kind: 'link', target: 'SKILL.md' }] },
|
|
382
|
+
{ what: 'a hard link', formats: ['tar'], reason: 'hardlink', entries: (prefix) => [{ name: `${prefix}twin`, kind: 'hardlink', target: `${prefix}SKILL.md` }] },
|
|
383
|
+
{
|
|
384
|
+
what: 'a symbolic link and a file under it',
|
|
385
|
+
formats: BOTH,
|
|
386
|
+
reason: 'link',
|
|
387
|
+
entries: (prefix) => [{ name: `${prefix}out`, kind: 'link', target: '..' }, { name: `${prefix}out/planted.txt`, data: 'planted' }],
|
|
388
|
+
},
|
|
389
|
+
{ what: 'a `..` name', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}../../../planted.txt`, data: 'planted' }] },
|
|
390
|
+
{ what: 'an absolute name', formats: BOTH, reason: UNSAFE_NAME, entries: () => [{ name: '/planted.txt', data: 'planted' }] },
|
|
391
|
+
{ what: 'a drive-letter name', formats: BOTH, reason: UNSAFE_NAME, entries: () => [{ name: String.raw `C:\planted.txt`, data: 'planted' }] },
|
|
392
|
+
{ what: 'a UNC name', formats: BOTH, reason: UNSAFE_NAME, entries: () => [{ name: String.raw `\\host\share\planted.txt`, data: 'planted' }] },
|
|
393
|
+
// Names Windows cannot hold as spelled — refused on every host, so one archive has one verdict everywhere.
|
|
394
|
+
{ what: 'a name holding a `:` (an NTFS stream)', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}notes:v2.md`, data: 'planted' }] },
|
|
395
|
+
{ what: 'a directory named with a `:`', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}a:b/x.md`, data: 'planted' }] },
|
|
396
|
+
{ what: 'a Windows device name', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}aux`, data: 'planted' }] },
|
|
397
|
+
{ what: 'a Windows device name with an extension', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}docs/Con.md`, data: 'planted' }] },
|
|
398
|
+
{ what: 'a name ending in a dot', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}notes.md.`, data: 'planted' }] },
|
|
399
|
+
{ what: 'a directory name ending in a space', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}docs /x.md`, data: 'planted' }] },
|
|
400
|
+
{ what: 'a name holding a `?`', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}faq?.md`, data: 'planted' }] },
|
|
401
|
+
{ what: 'a name holding a `|`', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}a|b.md`, data: 'planted' }] },
|
|
402
|
+
{ what: 'a directory named with a `<`, a `>` and a `"`', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}<"x">/a.md`, data: 'planted' }] },
|
|
403
|
+
{ what: 'a name holding a control character', formats: BOTH, reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}a${String.fromCodePoint(0x1f)}b.md`, data: 'planted' }] },
|
|
404
|
+
{ what: 'one name listed twice', formats: BOTH, reason: NAME_CLASH, entries: (prefix) => [{ name: `${prefix}twice.txt`, data: '1' }, { name: `${prefix}twice.txt`, data: '2' }] },
|
|
405
|
+
{
|
|
406
|
+
what: 'two names differing only in letter case',
|
|
407
|
+
formats: BOTH,
|
|
408
|
+
reason: NAME_CLASH,
|
|
409
|
+
entries: (prefix) => [{ name: `${prefix}Notes.md`, data: '1' }, { name: `${prefix}notes.md`, data: '2' }],
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
what: 'two names differing only in Unicode form',
|
|
413
|
+
formats: BOTH,
|
|
414
|
+
reason: NAME_CLASH,
|
|
415
|
+
entries: (prefix) => [{ name: `${prefix}caf${E_ACUTE_COMPOSED}.md`, data: '1' }, { name: `${prefix}caf${E_ACUTE_DECOMPOSED}.md`, data: '2' }],
|
|
416
|
+
},
|
|
417
|
+
{ what: 'a device', formats: BOTH, reason: 'special', entries: (prefix) => [{ name: `${prefix}dev`, kind: 'device' }] },
|
|
418
|
+
{ what: 'a named pipe', formats: BOTH, reason: 'special', entries: (prefix) => [{ name: `${prefix}pipe`, kind: 'fifo' }] },
|
|
419
|
+
// A ustar name field ends at its first NUL, so only a ZIP can spell one.
|
|
420
|
+
{ what: 'a name holding a NUL', formats: ['zip'], reason: UNSAFE_NAME, entries: (prefix) => [{ name: `${prefix}a${String.fromCodePoint(0)}.md`, data: 'planted' }] },
|
|
421
|
+
// The header spells a harmless name; the record before it says what the entry is really called.
|
|
422
|
+
{
|
|
423
|
+
what: 'a PAX header renaming a harmless entry to a `..` name',
|
|
424
|
+
formats: ['tar'],
|
|
425
|
+
reason: UNSAFE_NAME,
|
|
426
|
+
entries: (prefix) => [{ name: 'PaxHeader/harmless.txt', tarType: 'x', data: paxRecord('path', `${prefix}../../../planted.txt`) }, { name: `${prefix}harmless.txt`, data: 'planted' }],
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
what: 'a GNU long-name record renaming a harmless entry to a `..` name',
|
|
430
|
+
formats: ['tar'],
|
|
431
|
+
reason: UNSAFE_NAME,
|
|
432
|
+
entries: (prefix) => [{ name: '././@LongLink', tarType: 'L', data: `${prefix}../../../planted.txt${String.fromCodePoint(0)}` }, { name: `${prefix}harmless.txt`, data: 'planted' }],
|
|
433
|
+
},
|
|
434
|
+
// An entry of a type the tar reader's library skips: dropped silently, the archive would install without it.
|
|
435
|
+
{ what: 'a sparse file', formats: ['tar'], reason: 'special', entries: (prefix) => [{ name: `${prefix}sparse.bin`, tarType: 'S', data: 'x' }] },
|
|
436
|
+
{ what: 'an entry of a type no tar defines', formats: ['tar'], reason: 'special', entries: (prefix) => [{ name: `${prefix}odd.bin`, tarType: 'Z', data: 'x' }] },
|
|
437
|
+
{
|
|
438
|
+
what: 'more entries than the limit',
|
|
439
|
+
formats: BOTH,
|
|
440
|
+
reason: 'too-many-entries',
|
|
441
|
+
entries: (prefix) => Array.from({ length: limits.maxEntries + 1 }, (_unused, index) => ({ name: `${prefix}f${index}`, data: '' })),
|
|
442
|
+
},
|
|
443
|
+
// Declared, never held: the archive is refused on what its header says, before any of it is inflated.
|
|
444
|
+
{ what: 'more bytes than the limit', formats: BOTH, reason: 'too-large', entries: (prefix) => [{ name: `${prefix}big.bin`, data: '', declaredSize: limits.maxBytes + 1 }] },
|
|
445
|
+
...ZIP_FRAMING_ROWS,
|
|
446
|
+
...ZIP_PADDED_ROWS,
|
|
447
|
+
];
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=archive-fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-fixtures.js","sourceRoot":"","sources":["../../src/testing/archive-fixtures.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
export declare const NODE_EXECUTABLE: string;
|
|
20
20
|
/** The names to try in one `PATH` directory: `PATHEXT` variants on Windows, the bare name elsewhere. */
|
|
21
21
|
export declare function executableCandidates(name: string, platform: NodeJS.Platform, pathext: string | undefined): string[];
|
|
22
|
+
/**
|
|
23
|
+
* The first executable named `name` on `PATH`, absolute — or `undefined` when
|
|
24
|
+
* there is none. For a test that asks WHETHER a tool is installed (and skips
|
|
25
|
+
* without it) rather than one that needs it.
|
|
26
|
+
*/
|
|
27
|
+
export declare function findExecutable(name: string): string | undefined;
|
|
22
28
|
/**
|
|
23
29
|
* The first executable named `name` on `PATH`, absolute.
|
|
24
30
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executables.d.ts","sourceRoot":"","sources":["../../src/testing/executables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,8CAA8C;AAC9C,eAAO,MAAM,eAAe,EAAE,MAAyB,CAAC;AAExD,wGAAwG;AACxG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAInH;AAcD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"executables.d.ts","sourceRoot":"","sources":["../../src/testing/executables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,8CAA8C;AAC9C,eAAO,MAAM,eAAe,EAAE,MAAyB,CAAC;AAExD,wGAAwG;AACxG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAInH;AAcD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAU/D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAItD;AAID,yEAAyE;AACzE,wBAAgB,aAAa,IAAI,MAAM,CAGtC"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { accessSync, constants, statSync } from 'node:fs';
|
|
19
19
|
import { delimiter } from 'node:path';
|
|
20
|
-
import {
|
|
20
|
+
import { fsFaultOf } from '../errors/errno-table.js';
|
|
21
21
|
import { safePath } from '../path-core.js';
|
|
22
22
|
/** The `node` running this test, absolute. */
|
|
23
23
|
export const NODE_EXECUTABLE = process.execPath;
|
|
@@ -36,19 +36,17 @@ function isExecutableFile(full) {
|
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
38
|
// Absent or not executable here: the next directory on PATH may have it.
|
|
39
|
-
if (
|
|
39
|
+
if (fsFaultOf(error) !== undefined)
|
|
40
40
|
return false;
|
|
41
41
|
throw error;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
* The first executable named `name` on `PATH`, absolute
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* fixture that needs `git` and has none should fail at the first spawn with
|
|
49
|
-
* the reason, not with the OS's `ENOENT` for a bare word.
|
|
45
|
+
* The first executable named `name` on `PATH`, absolute — or `undefined` when
|
|
46
|
+
* there is none. For a test that asks WHETHER a tool is installed (and skips
|
|
47
|
+
* without it) rather than one that needs it.
|
|
50
48
|
*/
|
|
51
|
-
export function
|
|
49
|
+
export function findExecutable(name) {
|
|
52
50
|
const candidates = executableCandidates(name, process.platform, process.env['PATHEXT']);
|
|
53
51
|
for (const dir of (process.env['PATH'] ?? '').split(delimiter)) {
|
|
54
52
|
if (dir === '')
|
|
@@ -59,7 +57,20 @@ export function resolveExecutable(name) {
|
|
|
59
57
|
return full;
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
|
-
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The first executable named `name` on `PATH`, absolute.
|
|
64
|
+
*
|
|
65
|
+
* @throws {Error} when nothing on `PATH` is executable under that name — a
|
|
66
|
+
* fixture that needs `git` and has none should fail at the first spawn with
|
|
67
|
+
* the reason, not with the OS's `ENOENT` for a bare word.
|
|
68
|
+
*/
|
|
69
|
+
export function resolveExecutable(name) {
|
|
70
|
+
const found = findExecutable(name);
|
|
71
|
+
if (found === undefined)
|
|
72
|
+
throw new Error(`No executable named "${name}" on PATH (${process.env['PATH'] ?? '<unset>'})`);
|
|
73
|
+
return found;
|
|
63
74
|
}
|
|
64
75
|
let resolvedGit;
|
|
65
76
|
/** `git`, absolute, resolved on first use and cached for the process. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executables.js","sourceRoot":"","sources":["../../src/testing/executables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"executables.js","sourceRoot":"","sources":["../../src/testing/executables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,8CAA8C;AAC9C,MAAM,CAAC,MAAM,eAAe,GAAW,OAAO,CAAC,QAAQ,CAAC;AAExD,wGAAwG;AACxG,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,QAAyB,EAAE,OAA2B;IACvG,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,CAAC,OAAO,IAAI,qBAAqB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,kIAAkI;AAClI,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yEAAyE;QACzE,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACjD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACxF,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/D,IAAI,GAAG,KAAK,EAAE;YAAE,SAAS;QACzB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC3C,IAAI,gBAAgB,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,cAAc,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC;IACxH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,IAAI,WAA+B,CAAC;AAEpC,yEAAyE;AACzE,MAAM,UAAU,aAAa;IAC3B,WAAW,KAAK,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `node --import <utils dist>/testing/fault-fs-preload.js <cli dist>/bin.js ...` — the fs fault
|
|
3
|
+
* injector for a SPAWNED process, so a system test can fault the real binary the way the fault
|
|
4
|
+
* matrix faults a verb in-process.
|
|
5
|
+
*
|
|
6
|
+
* It reads `VAT_FAULT_FS` (`{"within": "<dir>", "faults": [{"family", "op", "pathIncludes", "nth",
|
|
7
|
+
* "errno"}]}`, see {@link faultFsSpecOf}) and installs the faults before the program's first
|
|
8
|
+
* module loads. The session lives as long as the process: nothing restores it.
|
|
9
|
+
*
|
|
10
|
+
* Importing this module IS the installation, so it is never re-exported from the `./testing`
|
|
11
|
+
* barrel. With `VAT_FAULT_FS` unset or empty it does nothing.
|
|
12
|
+
*
|
|
13
|
+
* ⛔ Framework-free, like everything under `testing/`.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=fault-fs-preload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fault-fs-preload.d.ts","sourceRoot":"","sources":["../../src/testing/fault-fs-preload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `node --import <utils dist>/testing/fault-fs-preload.js <cli dist>/bin.js ...` — the fs fault
|
|
3
|
+
* injector for a SPAWNED process, so a system test can fault the real binary the way the fault
|
|
4
|
+
* matrix faults a verb in-process.
|
|
5
|
+
*
|
|
6
|
+
* It reads `VAT_FAULT_FS` (`{"within": "<dir>", "faults": [{"family", "op", "pathIncludes", "nth",
|
|
7
|
+
* "errno"}]}`, see {@link faultFsSpecOf}) and installs the faults before the program's first
|
|
8
|
+
* module loads. The session lives as long as the process: nothing restores it.
|
|
9
|
+
*
|
|
10
|
+
* Importing this module IS the installation, so it is never re-exported from the `./testing`
|
|
11
|
+
* barrel. With `VAT_FAULT_FS` unset or empty it does nothing.
|
|
12
|
+
*
|
|
13
|
+
* ⛔ Framework-free, like everything under `testing/`.
|
|
14
|
+
*/
|
|
15
|
+
import { installFaultFs } from './fault-fs.js';
|
|
16
|
+
import { faultFsSpecOf, faultRuleOf } from './fault-spec.js';
|
|
17
|
+
const text = process.env['VAT_FAULT_FS'];
|
|
18
|
+
if (text !== undefined && text !== '') {
|
|
19
|
+
const spec = faultFsSpecOf(text);
|
|
20
|
+
installFaultFs({ within: spec.within, faults: spec.faults.map((fault) => faultRuleOf(fault)) });
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=fault-fs-preload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fault-fs-preload.js","sourceRoot":"","sources":["../../src/testing/fault-fs-preload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AACzC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AAClG,CAAC"}
|