@poe-platform/safe-bash 0.1.614 → 0.1.616
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/dist/safe-bash/commands/archive/unzip.js +1 -1
- package/dist/safe-bash/commands/archive/unzip.js.map +1 -1
- package/dist/safe-bash/commands/archive/zip/options.d.ts +7 -0
- package/dist/safe-bash/commands/archive/zip/options.d.ts.map +1 -0
- package/dist/safe-bash/commands/archive/zip/options.js +50 -0
- package/dist/safe-bash/commands/archive/zip/options.js.map +1 -0
- package/dist/safe-bash/commands/archive/zip/safety.d.ts +2 -0
- package/dist/safe-bash/commands/archive/zip/safety.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip/safety.js +4 -0
- package/dist/safe-bash/commands/archive/zip/safety.js.map +1 -1
- package/dist/safe-bash/commands/archive/zip-format.d.ts +2 -2
- package/dist/safe-bash/commands/archive/zip-format.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip-format.js +26 -14
- package/dist/safe-bash/commands/archive/zip-format.js.map +1 -1
- package/dist/safe-bash/commands/archive/zip.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip.js +130 -49
- package/dist/safe-bash/commands/archive/zip.js.map +1 -1
- package/dist/safe-bash/core.browser.js +241 -54
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/package.json +2 -2
|
@@ -3245,7 +3245,7 @@ async function parseEnvOptions(args, environment, signal, argumentValues) {
|
|
|
3245
3245
|
const values = /* @__PURE__ */ new Map();
|
|
3246
3246
|
const operands = [];
|
|
3247
3247
|
const operandValues = [];
|
|
3248
|
-
const
|
|
3248
|
+
const longOptions2 = /* @__PURE__ */ new Map([
|
|
3249
3249
|
["ignore-environment", "i"],
|
|
3250
3250
|
["unset", "u"],
|
|
3251
3251
|
["null", "0"],
|
|
@@ -3280,7 +3280,7 @@ async function parseEnvOptions(args, environment, signal, argumentValues) {
|
|
|
3280
3280
|
if (argument2.startsWith("--")) {
|
|
3281
3281
|
const equals = argument2.indexOf("=");
|
|
3282
3282
|
const name2 = argument2.slice(2, equals < 0 ? void 0 : equals);
|
|
3283
|
-
const key =
|
|
3283
|
+
const key = longOptions2.get(name2);
|
|
3284
3284
|
if (!key) throw new UsageError(`unrecognized option '${argument2}'`);
|
|
3285
3285
|
const required = key === "u" || key === "C" || key === "S";
|
|
3286
3286
|
if (!required && equals >= 0) throw new UsageError(`option '--${name2}' does not take an argument`);
|
|
@@ -3555,11 +3555,11 @@ function executionCommands(execute4, configuration = {}) {
|
|
|
3555
3555
|
const operandIndices = [];
|
|
3556
3556
|
let replacementOrigin;
|
|
3557
3557
|
const shortOptions = "0rn:s:I:d:tP:xE:";
|
|
3558
|
-
const
|
|
3558
|
+
const longOptions2 = { null: "0", "no-run-if-empty": "r", "max-args": "n", "max-chars": "s", replace: "I", delimiter: "d", verbose: "t", "max-procs": "P", exit: "x", eof: "E" };
|
|
3559
3559
|
const parsed = options(
|
|
3560
3560
|
argumentValues.args,
|
|
3561
3561
|
shortOptions,
|
|
3562
|
-
|
|
3562
|
+
longOptions2,
|
|
3563
3563
|
true,
|
|
3564
3564
|
(index) => {
|
|
3565
3565
|
operandIndices.push(index);
|
|
@@ -26729,7 +26729,8 @@ function entryBounds(entry, limits) {
|
|
|
26729
26729
|
format(entry.method, entry.flags ?? 2048, entry.method === 8 || (entry.flags ?? 0) & 8 ? 20 : 10);
|
|
26730
26730
|
if (entry.directory !== entry.name.endsWith("/") || entry.directory && (entry.symlink || entry.size !== 0)) fail("ZIP inconsistent directory metadata");
|
|
26731
26731
|
const type = entry.mode & 61440;
|
|
26732
|
-
|
|
26732
|
+
const pipePayload = !entry.directory && !entry.symlink && type === 4096;
|
|
26733
|
+
if (type !== 0 && !pipePayload && type !== (entry.directory ? 16384 : entry.symlink ? 40960 : 32768)) fail("ZIP unsupported or conflicting file type");
|
|
26733
26734
|
if (!Number.isFinite(entry.modified.getTime())) fail("ZIP invalid modification time");
|
|
26734
26735
|
}
|
|
26735
26736
|
async function copyBytes(source2, destination2, start, chunkSize2, signal) {
|
|
@@ -26896,7 +26897,7 @@ async function* decodeZipEntry(entry, limits, signal) {
|
|
|
26896
26897
|
await reader.close();
|
|
26897
26898
|
}
|
|
26898
26899
|
}
|
|
26899
|
-
async function makeZipEntry(name2, bytes3, attributes, limits, signal, level = 6) {
|
|
26900
|
+
async function makeZipEntry(name2, bytes3, attributes, limits, signal, level = 6, forceCompression = false) {
|
|
26900
26901
|
const chunkSize2 = admit(limits, signal);
|
|
26901
26902
|
const entry = { name: name2, data: bytes3, size: bytes3.length, method: 0, crc32: 0, ...attributes, modified: new Date(attributes.modified.getTime()) };
|
|
26902
26903
|
entryBounds(entry, limits);
|
|
@@ -26908,15 +26909,16 @@ async function makeZipEntry(name2, bytes3, attributes, limits, signal, level = 6
|
|
|
26908
26909
|
yield bytes3;
|
|
26909
26910
|
})(), signal);
|
|
26910
26911
|
try {
|
|
26911
|
-
if (level !== 0 && bytes3.length && !entry.directory && !entry.symlink) {
|
|
26912
|
+
if (level !== 0 && (bytes3.length || forceCompression) && !entry.directory && !entry.symlink) {
|
|
26912
26913
|
const chunks = [];
|
|
26913
26914
|
let length = 0;
|
|
26914
26915
|
for await (const chunk of codec(reader, { mode: "deflate-raw", chunkSize: chunkSize2, level }, signal)) {
|
|
26915
26916
|
length += chunk.length;
|
|
26916
|
-
if (length
|
|
26917
|
+
if (length > limits.maxArchiveBytes) fail("ZIP compressed byte limit exceeded");
|
|
26918
|
+
if (!forceCompression && length >= bytes3.length) break;
|
|
26917
26919
|
chunks.push(new Uint8Array(chunk));
|
|
26918
26920
|
}
|
|
26919
|
-
if (length < bytes3.length) {
|
|
26921
|
+
if (forceCompression || length < bytes3.length) {
|
|
26920
26922
|
entry.data = new Uint8Array(length);
|
|
26921
26923
|
let offset = 0;
|
|
26922
26924
|
for (const chunk of chunks) {
|
|
@@ -26946,7 +26948,7 @@ function timestampExtra(modified) {
|
|
|
26946
26948
|
view.setInt32(5, seconds, true);
|
|
26947
26949
|
return bytes3;
|
|
26948
26950
|
}
|
|
26949
|
-
async function writeZipArchive(archive, limits, signal) {
|
|
26951
|
+
async function writeZipArchive(archive, limits, signal, descriptors = false) {
|
|
26950
26952
|
const chunkSize2 = admit(limits, signal);
|
|
26951
26953
|
number3(archive.entries.length, Math.min(limits.maxMembers, 65534), "member");
|
|
26952
26954
|
number3(archive.comment.length, Math.min(limits.maxTextBytes, 65535), "archive comment");
|
|
@@ -26961,7 +26963,8 @@ async function writeZipArchive(archive, limits, signal) {
|
|
|
26961
26963
|
total += entry.size;
|
|
26962
26964
|
number3(total, limits.maxTotalBytes, "total byte");
|
|
26963
26965
|
const rawName = entry.rawName ?? pathBytes(entry.name, limits);
|
|
26964
|
-
const
|
|
26966
|
+
const descriptor = descriptors && !entry.directory;
|
|
26967
|
+
const flags3 = (entry.flags ?? 2048) & ~8 | (descriptor ? 8 : 0);
|
|
26965
26968
|
const comment2 = entry.comment ?? new Uint8Array();
|
|
26966
26969
|
number3(comment2.length, Math.min(limits.maxTextBytes, 65535), "entry comment");
|
|
26967
26970
|
if (flags3 & 2048) text2(comment2);
|
|
@@ -26989,8 +26992,8 @@ async function writeZipArchive(archive, limits, signal) {
|
|
|
26989
26992
|
if (mode !== entry.mode || Boolean(entry.externalAttributes & 16) && !entry.directory) fail("ZIP retained file attributes mismatch");
|
|
26990
26993
|
}
|
|
26991
26994
|
encoded2.push({ entry, rawName, flags: flags3, localExtra, centralExtra, comment: comment2, date: date2, time, offset: localLength });
|
|
26992
|
-
localLength += 30 + rawName.length + localExtra.length + entry.data.length;
|
|
26993
|
-
length += 76 + 2 * rawName.length + localExtra.length + centralExtra.length + comment2.length + entry.data.length;
|
|
26995
|
+
localLength += 30 + rawName.length + localExtra.length + entry.data.length + (descriptor ? 16 : 0);
|
|
26996
|
+
length += 76 + 2 * rawName.length + localExtra.length + centralExtra.length + comment2.length + entry.data.length + (descriptor ? 16 : 0);
|
|
26994
26997
|
number3(length, Math.min(limits.maxArchiveBytes, 4294967294), "archive byte");
|
|
26995
26998
|
}
|
|
26996
26999
|
number3(length, Math.min(limits.maxArchiveBytes, 4294967294), "archive byte");
|
|
@@ -27000,21 +27003,28 @@ async function writeZipArchive(archive, limits, signal) {
|
|
|
27000
27003
|
for (const item of encoded2) {
|
|
27001
27004
|
await yieldTurn(signal);
|
|
27002
27005
|
const { entry, rawName, flags: flags3, localExtra, centralExtra, comment: comment2, date: date2, time, offset } = item;
|
|
27003
|
-
const version = entry.method === 8 ? 20 : 10;
|
|
27006
|
+
const version = entry.method === 8 || flags3 & 8 ? 20 : 10;
|
|
27004
27007
|
view.setUint32(offset, 67324752, true);
|
|
27005
27008
|
view.setUint16(offset + 4, version, true);
|
|
27006
27009
|
view.setUint16(offset + 6, flags3, true);
|
|
27007
27010
|
view.setUint16(offset + 8, entry.method, true);
|
|
27008
27011
|
view.setUint16(offset + 10, time, true);
|
|
27009
27012
|
view.setUint16(offset + 12, date2, true);
|
|
27010
|
-
view.setUint32(offset + 14, entry.crc32, true);
|
|
27011
|
-
view.setUint32(offset + 18, entry.data.length, true);
|
|
27012
|
-
view.setUint32(offset + 22, entry.size, true);
|
|
27013
|
+
view.setUint32(offset + 14, flags3 & 8 ? 0 : entry.crc32, true);
|
|
27014
|
+
view.setUint32(offset + 18, flags3 & 8 ? 0 : entry.data.length, true);
|
|
27015
|
+
view.setUint32(offset + 22, flags3 & 8 ? 0 : entry.size, true);
|
|
27013
27016
|
view.setUint16(offset + 26, rawName.length, true);
|
|
27014
27017
|
view.setUint16(offset + 28, localExtra.length, true);
|
|
27015
27018
|
bytes3.set(rawName, offset + 30);
|
|
27016
27019
|
bytes3.set(localExtra, offset + 30 + rawName.length);
|
|
27017
27020
|
await copyBytes(entry.data, bytes3, offset + 30 + rawName.length + localExtra.length, chunkSize2, signal);
|
|
27021
|
+
if (flags3 & 8) {
|
|
27022
|
+
const descriptor = offset + 30 + rawName.length + localExtra.length + entry.data.length;
|
|
27023
|
+
view.setUint32(descriptor, 134695760, true);
|
|
27024
|
+
view.setUint32(descriptor + 4, entry.crc32, true);
|
|
27025
|
+
view.setUint32(descriptor + 8, entry.data.length, true);
|
|
27026
|
+
view.setUint32(descriptor + 12, entry.size, true);
|
|
27027
|
+
}
|
|
27018
27028
|
view.setUint32(central, 33639248, true);
|
|
27019
27029
|
view.setUint16(central + 4, entry.versionMadeBy ?? 798, true);
|
|
27020
27030
|
view.setUint16(central + 6, version, true);
|
|
@@ -27029,7 +27039,8 @@ async function writeZipArchive(archive, limits, signal) {
|
|
|
27029
27039
|
view.setUint16(central + 30, centralExtra.length, true);
|
|
27030
27040
|
view.setUint16(central + 32, comment2.length, true);
|
|
27031
27041
|
view.setUint16(central + 36, entry.internalAttributes ?? 0, true);
|
|
27032
|
-
|
|
27042
|
+
const mode = entry.mode & 61440 ? entry.mode : entry.mode | (entry.directory ? 16384 : entry.symlink ? 40960 : 32768);
|
|
27043
|
+
view.setUint32(central + 38, entry.externalAttributes ?? mode * 65536 + (entry.directory ? 16 : 0), true);
|
|
27033
27044
|
view.setUint32(central + 42, offset, true);
|
|
27034
27045
|
bytes3.set(rawName, central + 46);
|
|
27035
27046
|
bytes3.set(centralExtra, central + 46 + rawName.length);
|
|
@@ -27066,6 +27077,7 @@ var ZipScope = class {
|
|
|
27066
27077
|
closedReason = new Error("ZIP command is closed");
|
|
27067
27078
|
drain;
|
|
27068
27079
|
work = 0;
|
|
27080
|
+
stdinSource;
|
|
27069
27081
|
close = () => {
|
|
27070
27082
|
if (!this.drain) {
|
|
27071
27083
|
this.drain = Promise.resolve().then(async () => {
|
|
@@ -27104,6 +27116,9 @@ var ZipScope = class {
|
|
|
27104
27116
|
throw error;
|
|
27105
27117
|
}
|
|
27106
27118
|
}
|
|
27119
|
+
get stdin() {
|
|
27120
|
+
return this.stdinSource ??= this.source(this.original.stdin);
|
|
27121
|
+
}
|
|
27107
27122
|
source(source2) {
|
|
27108
27123
|
const iterator = source2[Symbol.asyncIterator]();
|
|
27109
27124
|
let closing;
|
|
@@ -27376,7 +27391,8 @@ var Answers = class {
|
|
|
27376
27391
|
}
|
|
27377
27392
|
};
|
|
27378
27393
|
|
|
27379
|
-
// packages/safe-bash/src/commands/archive/zip.ts
|
|
27394
|
+
// packages/safe-bash/src/commands/archive/zip/options.ts
|
|
27395
|
+
init_platform();
|
|
27380
27396
|
var ZipFailure = class extends Error {
|
|
27381
27397
|
constructor(status2, label, detail) {
|
|
27382
27398
|
super(detail);
|
|
@@ -27386,6 +27402,107 @@ var ZipFailure = class extends Error {
|
|
|
27386
27402
|
status;
|
|
27387
27403
|
label;
|
|
27388
27404
|
};
|
|
27405
|
+
var longOptions = {
|
|
27406
|
+
"recurse-paths": "r",
|
|
27407
|
+
quiet: "q",
|
|
27408
|
+
"junk-paths": "j",
|
|
27409
|
+
"no-dir-entries": "D",
|
|
27410
|
+
symlinks: "y",
|
|
27411
|
+
test: "T",
|
|
27412
|
+
"names-stdin": "@",
|
|
27413
|
+
update: "u",
|
|
27414
|
+
freshen: "f",
|
|
27415
|
+
delete: "d",
|
|
27416
|
+
include: "i",
|
|
27417
|
+
exclude: "x",
|
|
27418
|
+
suffixes: "n",
|
|
27419
|
+
store: "0",
|
|
27420
|
+
"compression-method": "Z",
|
|
27421
|
+
"compress-1": "1",
|
|
27422
|
+
"compress-2": "2",
|
|
27423
|
+
"compress-3": "3",
|
|
27424
|
+
"compress-4": "4",
|
|
27425
|
+
"compress-5": "5",
|
|
27426
|
+
"compress-6": "6",
|
|
27427
|
+
"compress-7": "7",
|
|
27428
|
+
"compress-8": "8",
|
|
27429
|
+
"compress-9": "9"
|
|
27430
|
+
};
|
|
27431
|
+
var reservedOptions = [
|
|
27432
|
+
"adjust-sfx",
|
|
27433
|
+
"temp-path",
|
|
27434
|
+
"entry-comments",
|
|
27435
|
+
"display-bytes",
|
|
27436
|
+
"display-counts",
|
|
27437
|
+
"display-dots",
|
|
27438
|
+
"display-globaldots",
|
|
27439
|
+
"dot-size",
|
|
27440
|
+
"display-usize",
|
|
27441
|
+
"display-volume",
|
|
27442
|
+
"difference-archive",
|
|
27443
|
+
"encrypt",
|
|
27444
|
+
"fix",
|
|
27445
|
+
"fixfix",
|
|
27446
|
+
"fifo",
|
|
27447
|
+
"filesync",
|
|
27448
|
+
"force-descriptors",
|
|
27449
|
+
"force-zip64",
|
|
27450
|
+
"grow",
|
|
27451
|
+
"help",
|
|
27452
|
+
"more-help",
|
|
27453
|
+
"junk-sfx",
|
|
27454
|
+
"DOS-names",
|
|
27455
|
+
"to-crlf",
|
|
27456
|
+
"from-crlf",
|
|
27457
|
+
"logfile-path",
|
|
27458
|
+
"log-append",
|
|
27459
|
+
"log-info",
|
|
27460
|
+
"license",
|
|
27461
|
+
"move",
|
|
27462
|
+
"must-match",
|
|
27463
|
+
"no-wild",
|
|
27464
|
+
"latest-time",
|
|
27465
|
+
"output-file",
|
|
27466
|
+
"paths",
|
|
27467
|
+
"password",
|
|
27468
|
+
"recurse-patterns",
|
|
27469
|
+
"regex",
|
|
27470
|
+
"split-size",
|
|
27471
|
+
"split-pause",
|
|
27472
|
+
"split-verbose",
|
|
27473
|
+
"split-bell",
|
|
27474
|
+
"show-command",
|
|
27475
|
+
"show-debug",
|
|
27476
|
+
"show-files",
|
|
27477
|
+
"show-options",
|
|
27478
|
+
"from-date",
|
|
27479
|
+
"before-date",
|
|
27480
|
+
"unzip-command",
|
|
27481
|
+
"copy-entries",
|
|
27482
|
+
"verbose",
|
|
27483
|
+
"version",
|
|
27484
|
+
"wild-stop-dirs",
|
|
27485
|
+
"strip-extra",
|
|
27486
|
+
"archive-comment"
|
|
27487
|
+
];
|
|
27488
|
+
function normalizeZipOption(argument2) {
|
|
27489
|
+
if (!argument2.startsWith("--") || argument2 === "--") return argument2;
|
|
27490
|
+
const equal2 = argument2.indexOf("=");
|
|
27491
|
+
const name2 = argument2.slice(2, equal2 < 0 ? void 0 : equal2);
|
|
27492
|
+
const names = [...Object.keys(longOptions), ...reservedOptions];
|
|
27493
|
+
const matches2 = names.includes(name2) ? [name2] : names.filter((option) => option.startsWith(name2));
|
|
27494
|
+
if (matches2.length > 1) throw new ZipFailure(16, "Invalid command arguments", `long option '${name2}' ambiguous`);
|
|
27495
|
+
const matched = matches2[0];
|
|
27496
|
+
const short = matched === void 0 ? void 0 : longOptions[matched];
|
|
27497
|
+
if (!short) throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
|
|
27498
|
+
if (equal2 >= 0 && short !== "i" && short !== "x" && short !== "n" && short !== "Z") {
|
|
27499
|
+
throw new ZipFailure(16, "Invalid command arguments", `option '${matched}' does not allow a value`);
|
|
27500
|
+
}
|
|
27501
|
+
return `-${short}${equal2 < 0 ? "" : argument2.slice(equal2)}`;
|
|
27502
|
+
}
|
|
27503
|
+
|
|
27504
|
+
// packages/safe-bash/src/commands/archive/zip.ts
|
|
27505
|
+
var defaultStoreSuffixes = [".Z", ".zip", ".zoo", ".arc", ".lzh", ".arj"];
|
|
27389
27506
|
async function parse12(scope, limits) {
|
|
27390
27507
|
const context2 = scope.context;
|
|
27391
27508
|
if (context2.args.length > limits.maxArgumentBytes) fail("argument count limit exceeded");
|
|
@@ -27414,6 +27531,8 @@ async function parse12(scope, limits) {
|
|
|
27414
27531
|
let storeLinks = false;
|
|
27415
27532
|
let test = false;
|
|
27416
27533
|
let level = 6;
|
|
27534
|
+
let method = "deflate";
|
|
27535
|
+
let suffixes = defaultStoreSuffixes;
|
|
27417
27536
|
let stdinNames = false;
|
|
27418
27537
|
let literal = false;
|
|
27419
27538
|
let firstOperand = -1;
|
|
@@ -27421,8 +27540,9 @@ async function parse12(scope, limits) {
|
|
|
27421
27540
|
const includes = [];
|
|
27422
27541
|
const excludes = [];
|
|
27423
27542
|
for (let index = 0; index < context2.args.length; index++) {
|
|
27424
|
-
const
|
|
27425
|
-
checkPath(
|
|
27543
|
+
const original = context2.args[index];
|
|
27544
|
+
checkPath(original, limits);
|
|
27545
|
+
const argument2 = literal ? original : normalizeZipOption(original);
|
|
27426
27546
|
if (!literal && argument2 === "--") {
|
|
27427
27547
|
if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "can't use -- before archive name");
|
|
27428
27548
|
literal = true;
|
|
@@ -27440,17 +27560,43 @@ async function parse12(scope, limits) {
|
|
|
27440
27560
|
else if (flag === "y") storeLinks = true;
|
|
27441
27561
|
else if (flag === "T") test = true;
|
|
27442
27562
|
else if (flag === "@") stdinNames = true;
|
|
27443
|
-
else if (flag !== void 0 && flag >= "0" && flag <= "9")
|
|
27444
|
-
|
|
27563
|
+
else if (flag !== void 0 && flag >= "0" && flag <= "9") {
|
|
27564
|
+
level = Number(flag);
|
|
27565
|
+
if (level === 0) method = "store";
|
|
27566
|
+
} else if (flag === "n" || flag === "Z") {
|
|
27567
|
+
let value2 = argument2.slice(offset + 1);
|
|
27568
|
+
if (!value2) {
|
|
27569
|
+
const next = context2.args[index + 1];
|
|
27570
|
+
if (next === void 0 || next.startsWith("-") && next !== "-") throw new ZipFailure(16, "Invalid command arguments", `option '${flag}' requires a value`);
|
|
27571
|
+
value2 = next;
|
|
27572
|
+
index++;
|
|
27573
|
+
}
|
|
27574
|
+
if (value2.startsWith("=")) value2 = value2.slice(1);
|
|
27575
|
+
if (flag === "n") {
|
|
27576
|
+
suffixes = value2 ? value2.split(":").filter((suffix2) => suffix2.length > 0) : defaultStoreSuffixes;
|
|
27577
|
+
if (value2 && suffixes.length > limits.maxMembers) fail("suffix count limit exceeded");
|
|
27578
|
+
} else {
|
|
27579
|
+
const matches2 = ["store", "deflate", "bzip2"].filter((name2) => name2.startsWith(value2.toLowerCase()));
|
|
27580
|
+
const selected = matches2.length === 1 ? matches2[0] : void 0;
|
|
27581
|
+
if (!selected) throw new ZipFailure(16, "Invalid command arguments", "Option -Z (--compression-method): unknown method");
|
|
27582
|
+
if (selected === "bzip2") throw new ZipFailure(19, "Not supported", "Compression method bzip2 not enabled");
|
|
27583
|
+
method = selected === "store" ? "store" : "deflate";
|
|
27584
|
+
}
|
|
27585
|
+
break;
|
|
27586
|
+
} else if (flag === "i" || flag === "x") {
|
|
27445
27587
|
const patterns2 = flag === "i" ? includes : excludes;
|
|
27446
27588
|
const before = patterns2.length;
|
|
27447
27589
|
const append = (pattern) => {
|
|
27448
|
-
checkPath(pattern, limits);
|
|
27590
|
+
if (pattern) checkPath(pattern, limits);
|
|
27449
27591
|
if (includes.length + excludes.length >= limits.maxMembers) fail("pattern count limit exceeded");
|
|
27450
27592
|
patterns2.push(pattern);
|
|
27451
27593
|
};
|
|
27452
|
-
|
|
27453
|
-
|
|
27594
|
+
const attached = offset + 1 < argument2.length;
|
|
27595
|
+
if (attached) {
|
|
27596
|
+
const value2 = argument2.slice(offset + 1);
|
|
27597
|
+
append(value2.startsWith("=") ? value2.slice(1) : value2);
|
|
27598
|
+
}
|
|
27599
|
+
while (!attached && index + 1 < context2.args.length) {
|
|
27454
27600
|
const next = context2.args[index + 1];
|
|
27455
27601
|
if (next === "@") {
|
|
27456
27602
|
index++;
|
|
@@ -27471,13 +27617,16 @@ async function parse12(scope, limits) {
|
|
|
27471
27617
|
operands.push(argument2);
|
|
27472
27618
|
}
|
|
27473
27619
|
}
|
|
27474
|
-
if (archive === void 0)
|
|
27475
|
-
|
|
27476
|
-
|
|
27620
|
+
if (archive === void 0) {
|
|
27621
|
+
if (action !== "add") throw new ZipFailure(16, "Invalid command arguments", "expected archive name");
|
|
27622
|
+
archive = "-";
|
|
27623
|
+
if (!stdinNames) operands.push("-");
|
|
27624
|
+
}
|
|
27625
|
+
if (archive !== "-" && !archive.slice(archive.lastIndexOf("/") + 1).includes(".")) archive += ".zip";
|
|
27477
27626
|
checkPath(archive, limits);
|
|
27478
27627
|
const names = [];
|
|
27479
27628
|
if (stdinNames) {
|
|
27480
|
-
const input3 = await collectBytes(scope.
|
|
27629
|
+
const input3 = await collectBytes(scope.stdin, { maxBytes: limits.maxFilesFromBytes, signal: context2.signal });
|
|
27481
27630
|
let start = 0;
|
|
27482
27631
|
let lines3 = 0;
|
|
27483
27632
|
for (let end = 0; end <= input3.length; end++) {
|
|
@@ -27496,7 +27645,7 @@ async function parse12(scope, limits) {
|
|
|
27496
27645
|
start = end + 1;
|
|
27497
27646
|
}
|
|
27498
27647
|
}
|
|
27499
|
-
return { action, archive, recursive, quiet, junkPaths, omitDirectories, storeLinks, test, includes, excludes, level, operands: [...names, ...operands], firstOperand };
|
|
27648
|
+
return { action, archive, recursive, quiet, junkPaths, omitDirectories, storeLinks, test, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
|
|
27500
27649
|
}
|
|
27501
27650
|
function memberName(path, limits) {
|
|
27502
27651
|
if (path.startsWith("//") && !path.startsWith("///")) fail("UNC source paths are unsupported");
|
|
@@ -27538,21 +27687,29 @@ async function filterName(name2, selection, includeCount) {
|
|
|
27538
27687
|
async function prepare(scope, parsed, budget) {
|
|
27539
27688
|
const context2 = scope.context;
|
|
27540
27689
|
const limits = budget.limits;
|
|
27541
|
-
|
|
27542
|
-
|
|
27543
|
-
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27690
|
+
if (parsed.archive === "-" && parsed.action !== "add") throw new ZipFailure(16, "Invalid command arguments", "can't use -d, -f, -u, -U, or -g on stdout\n");
|
|
27691
|
+
let publication;
|
|
27692
|
+
if (parsed.archive !== "-") {
|
|
27693
|
+
const outputName = vfsPath(context2.cwd, parsed.archive);
|
|
27694
|
+
const parentName = dirname(outputName);
|
|
27695
|
+
const parent = await scope.operation(() => context2.fs.realpath(parentName, { signal: context2.signal }));
|
|
27696
|
+
const parentStat = await scope.operation(() => context2.fs.lstat(parent, { signal: context2.signal }));
|
|
27697
|
+
const output3 = `${parent === "/" ? "" : parent}/${outputName.slice(outputName.lastIndexOf("/") + 1)}`;
|
|
27698
|
+
checkPath(output3, limits);
|
|
27699
|
+
const existing3 = await scope.stat(output3);
|
|
27700
|
+
publication = { output: output3, parentName, parent, parentStat, existing: existing3 };
|
|
27701
|
+
}
|
|
27702
|
+
const output2 = publication?.output;
|
|
27703
|
+
const existing2 = publication?.existing;
|
|
27704
|
+
if (parsed.archive === "-" && parsed.test && !parsed.quiet) await budget.output(" zip warning: can't use -T on stdout, -T ignored\n");
|
|
27548
27705
|
if (existing2 && (existing2.type !== "file" || !hasIdentity(existing2) || existing2.nlink !== 1)) fail("updating archive requires a regular, single-link file with known backing identity; archive aliases are unsupported");
|
|
27549
27706
|
let archive = { entries: [], comment: new Uint8Array() };
|
|
27550
|
-
if (existing2) {
|
|
27707
|
+
if (existing2 && publication) {
|
|
27551
27708
|
if (!Number.isSafeInteger(existing2.size) || existing2.size < 0 || existing2.size > limits.maxArchiveBytes) fail("archive byte limit exceeded");
|
|
27552
|
-
const bytes4 = await collectBytes(scope.input(
|
|
27709
|
+
const bytes4 = await collectBytes(scope.input(publication.output), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
|
|
27553
27710
|
if (bytes4.length !== existing2.size) fail("archive changed while reading");
|
|
27554
27711
|
archive = await readZipArchive(bytes4, limits, context2.signal);
|
|
27555
|
-
const current = await scope.stat(
|
|
27712
|
+
const current = await scope.stat(publication.output);
|
|
27556
27713
|
if (!current || !unchanged4(existing2, current)) fail("archive changed while reading");
|
|
27557
27714
|
}
|
|
27558
27715
|
const old = new Map(archive.entries.map((entry) => [entry.name, entry]));
|
|
@@ -27565,12 +27722,35 @@ async function prepare(scope, parsed, budget) {
|
|
|
27565
27722
|
let visits = 0;
|
|
27566
27723
|
let work = 0;
|
|
27567
27724
|
let compressedBytes = 0;
|
|
27725
|
+
const encodeSelected = async (source2, name2, bytes4, attributes) => {
|
|
27726
|
+
const store = parsed.method === "store" || parsed.level !== 9 && parsed.suffixes.some((suffix2) => name2.endsWith(suffix2));
|
|
27727
|
+
if (!store && parsed.level === 0 && bytes4.length && !attributes.directory && !attributes.symlink) throw new ZipFailure(5, "Internal logic error", "bad pack level");
|
|
27728
|
+
const level = store ? 0 : parsed.level;
|
|
27729
|
+
let entry = await makeZipEntry(name2, bytes4, attributes, limits, context2.signal, level, parsed.archive === "-" && !store);
|
|
27730
|
+
const prior = old.get(name2);
|
|
27731
|
+
if (prior?.comment) entry = { ...entry, comment: prior.comment };
|
|
27732
|
+
if (entry.data.length > limits.maxArchiveBytes - compressedBytes) fail("archive byte limit exceeded");
|
|
27733
|
+
compressedBytes += entry.data.length;
|
|
27734
|
+
selected.set(name2, { entry, source: source2 });
|
|
27735
|
+
};
|
|
27568
27736
|
const visit = async (source2, name2, depth) => {
|
|
27569
27737
|
context2.signal.throwIfAborted();
|
|
27570
27738
|
if (++visits > limits.maxMembers) fail("traversal member limit exceeded");
|
|
27571
27739
|
if (++work > limits.maxPatternSteps) fail("archive work limit exceeded");
|
|
27572
27740
|
if (visits % 128 === 0) await yieldTurn(context2.signal);
|
|
27573
27741
|
if (depth > limits.maxDepth) fail("archive recursion depth limit exceeded");
|
|
27742
|
+
if (source2 === "-") {
|
|
27743
|
+
const previous = selected.get(name2);
|
|
27744
|
+
if (previous && previous.source !== source2) throw new ZipFailure(16, "Invalid command arguments", "cannot repeat names in zip file");
|
|
27745
|
+
if (previous || !await filterName(name2, selection, parsed.includes.length)) return;
|
|
27746
|
+
const prior2 = old.get(name2);
|
|
27747
|
+
const modified = /* @__PURE__ */ new Date();
|
|
27748
|
+
if (parsed.action === "freshen" && !prior2 || prior2 && (parsed.action === "update" || parsed.action === "freshen") && Math.floor(modified.getTime() / 1e3) <= Math.floor(prior2.modified.getTime() / 1e3)) return;
|
|
27749
|
+
const bytes4 = await collectBytes(scope.stdin, { maxBytes: Math.min(limits.maxEntryBytes, limits.maxTotalBytes - budget.totalBytes), signal: context2.signal });
|
|
27750
|
+
await budget.member(bytes4.length);
|
|
27751
|
+
await encodeSelected(source2, name2, bytes4, { modified, mode: 4528, directory: false, symlink: false });
|
|
27752
|
+
return;
|
|
27753
|
+
}
|
|
27574
27754
|
const path = vfsPath(context2.cwd, source2);
|
|
27575
27755
|
checkPath(path, limits);
|
|
27576
27756
|
let canonical;
|
|
@@ -27623,12 +27803,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27623
27803
|
if (!directory2 && bytes4.length !== stat.size) fail(`source changed while reading: ${source2}`);
|
|
27624
27804
|
const current = await inspectSource(scope, path, parsed.storeLinks);
|
|
27625
27805
|
if (current.canonical !== canonical || !unchanged4(stat, current.stat)) fail(`source changed while reading: ${source2}`);
|
|
27626
|
-
|
|
27627
|
-
if ([".z", ".zip", ".zoo", ".arc", ".lzh", ".arj"].some((suffix2) => name2.toLowerCase().endsWith(suffix2))) entry = { ...entry, method: 0, data: bytes4 };
|
|
27628
|
-
if (prior?.comment) entry = { ...entry, comment: prior.comment };
|
|
27629
|
-
if (entry.data.length > limits.maxArchiveBytes - compressedBytes) fail("archive byte limit exceeded");
|
|
27630
|
-
compressedBytes += entry.data.length;
|
|
27631
|
-
selected.set(name2, { entry, source: source2 });
|
|
27806
|
+
await encodeSelected(source2, name2, bytes4, { modified: new Date(stat.mtimeMs), mode: stat.mode, directory: directory2, symlink });
|
|
27632
27807
|
}
|
|
27633
27808
|
}
|
|
27634
27809
|
if (directory2 && parsed.recursive) {
|
|
@@ -27709,8 +27884,8 @@ async function prepare(scope, parsed, budget) {
|
|
|
27709
27884
|
append(entry, false);
|
|
27710
27885
|
}
|
|
27711
27886
|
if (!entries2.length) queue(" zip warning: zip file empty\n");
|
|
27712
|
-
const bytes3 = await writeZipArchive({ entries: entries2, comment: archive.comment }, limits, context2.signal);
|
|
27713
|
-
if (parsed.test) {
|
|
27887
|
+
const bytes3 = await writeZipArchive({ entries: entries2, comment: archive.comment }, limits, context2.signal, parsed.archive === "-");
|
|
27888
|
+
if (parsed.test && parsed.archive !== "-") {
|
|
27714
27889
|
for (const message3 of progress) await budget.output(message3);
|
|
27715
27890
|
progress.length = 0;
|
|
27716
27891
|
progressBytes = 0;
|
|
@@ -27735,7 +27910,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27735
27910
|
`);
|
|
27736
27911
|
}
|
|
27737
27912
|
}
|
|
27738
|
-
return {
|
|
27913
|
+
return { publication, bytes: bytes3, progress };
|
|
27739
27914
|
}
|
|
27740
27915
|
function createZipCommand(options2 = {}) {
|
|
27741
27916
|
const limits = settings2(options2);
|
|
@@ -27743,13 +27918,25 @@ function createZipCommand(options2 = {}) {
|
|
|
27743
27918
|
original.signal.throwIfAborted();
|
|
27744
27919
|
const scope = new ZipScope(original, limits);
|
|
27745
27920
|
const context2 = scope.context;
|
|
27746
|
-
|
|
27921
|
+
let budget = new Budget14(context2, limits);
|
|
27747
27922
|
try {
|
|
27748
27923
|
const parsed = await parse12(scope, limits);
|
|
27924
|
+
if (parsed.archive === "-") budget = new Budget14({ ...context2, stdout: context2.stderr }, limits);
|
|
27749
27925
|
const prepared = await prepare(scope, parsed, budget);
|
|
27750
27926
|
if (!prepared) return { exitCode: 12 };
|
|
27751
|
-
|
|
27752
|
-
|
|
27927
|
+
const publication = prepared.publication;
|
|
27928
|
+
if (publication) {
|
|
27929
|
+
await writeFileOutput(context2, prepared.bytes, () => scope.operation(() => publishZip(scope, { ...publication, bytes: prepared.bytes })));
|
|
27930
|
+
for (const message3 of prepared.progress) await budget.output(message3);
|
|
27931
|
+
} else {
|
|
27932
|
+
for (const message3 of prepared.progress) await budget.output(message3);
|
|
27933
|
+
const output2 = createOutputOperation(context2, context2.stdout);
|
|
27934
|
+
try {
|
|
27935
|
+
await writeBytes(output2.output, prepared.bytes, output2.signal);
|
|
27936
|
+
} finally {
|
|
27937
|
+
await output2.close();
|
|
27938
|
+
}
|
|
27939
|
+
}
|
|
27753
27940
|
return { exitCode: 0 };
|
|
27754
27941
|
} catch (error) {
|
|
27755
27942
|
original.signal.throwIfAborted();
|
|
@@ -28155,7 +28342,7 @@ function createUnzipCommand(options2 = {}) {
|
|
|
28155
28342
|
}
|
|
28156
28343
|
let path = extraction.member(root, entry.name);
|
|
28157
28344
|
const fileType = entry.mode & 61440;
|
|
28158
|
-
if (fileType && fileType !== 32768 && fileType !== 16384 && fileType !== 40960) fail("unsupported special ZIP entry");
|
|
28345
|
+
if (fileType && fileType !== 32768 && fileType !== 16384 && fileType !== 40960 && fileType !== 4096) fail("unsupported special ZIP entry");
|
|
28159
28346
|
if (path === root && !entry.directory) fail("entry would replace extraction root");
|
|
28160
28347
|
let shown = parsed.destination === void 0 ? entry.name : `${parsed.destination.endsWith("/") ? parsed.destination : `${parsed.destination}/`}${entry.name}`;
|
|
28161
28348
|
await extraction.parents(root, path, true);
|