@poe-platform/safe-bash 0.1.610 → 0.1.612
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/zip/safety.d.ts +1 -1
- package/dist/safe-bash/commands/archive/zip/safety.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip/safety.js.map +1 -1
- package/dist/safe-bash/commands/archive/zip-format.d.ts +1 -1
- package/dist/safe-bash/commands/archive/zip-format.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip-format.js +3 -3
- 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 +91 -12
- package/dist/safe-bash/commands/archive/zip.js.map +1 -1
- package/dist/safe-bash/core.browser.js +259 -197
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/package.json +2 -2
|
@@ -26896,7 +26896,7 @@ async function* decodeZipEntry(entry, limits, signal) {
|
|
|
26896
26896
|
await reader.close();
|
|
26897
26897
|
}
|
|
26898
26898
|
}
|
|
26899
|
-
async function makeZipEntry(name2, bytes3, attributes, limits, signal) {
|
|
26899
|
+
async function makeZipEntry(name2, bytes3, attributes, limits, signal, level = 6) {
|
|
26900
26900
|
const chunkSize2 = admit(limits, signal);
|
|
26901
26901
|
const entry = { name: name2, data: bytes3, size: bytes3.length, method: 0, crc32: 0, ...attributes, modified: new Date(attributes.modified.getTime()) };
|
|
26902
26902
|
entryBounds(entry, limits);
|
|
@@ -26908,10 +26908,10 @@ async function makeZipEntry(name2, bytes3, attributes, limits, signal) {
|
|
|
26908
26908
|
yield bytes3;
|
|
26909
26909
|
})(), signal);
|
|
26910
26910
|
try {
|
|
26911
|
-
if (bytes3.length && !entry.directory && !entry.symlink) {
|
|
26911
|
+
if (level !== 0 && bytes3.length && !entry.directory && !entry.symlink) {
|
|
26912
26912
|
const chunks = [];
|
|
26913
26913
|
let length = 0;
|
|
26914
|
-
for await (const chunk of codec(reader, { mode: "deflate-raw", chunkSize: chunkSize2 }, signal)) {
|
|
26914
|
+
for await (const chunk of codec(reader, { mode: "deflate-raw", chunkSize: chunkSize2, level }, signal)) {
|
|
26915
26915
|
length += chunk.length;
|
|
26916
26916
|
if (length >= bytes3.length) break;
|
|
26917
26917
|
chunks.push(new Uint8Array(chunk));
|
|
@@ -27194,6 +27194,188 @@ async function publishZip(scope, prepared) {
|
|
|
27194
27194
|
if (failure) throw failure.reason;
|
|
27195
27195
|
}
|
|
27196
27196
|
|
|
27197
|
+
// packages/safe-bash/src/commands/archive/unzip/arguments.ts
|
|
27198
|
+
init_platform();
|
|
27199
|
+
function parseArguments(context2, limits) {
|
|
27200
|
+
const { args } = context2;
|
|
27201
|
+
let bytes3 = 0;
|
|
27202
|
+
for (const argument2 of args) {
|
|
27203
|
+
bytes3 += import_buffer.Buffer.byteLength(argument2) + 1;
|
|
27204
|
+
if (bytes3 > limits.maxArgumentBytes) fail("argument byte limit exceeded");
|
|
27205
|
+
if (argument2.includes("\0")) fail("NUL in argument");
|
|
27206
|
+
}
|
|
27207
|
+
if (context2.argumentValues) {
|
|
27208
|
+
const argumentsValue = getCommandArguments(context2);
|
|
27209
|
+
let rawBytes = 0;
|
|
27210
|
+
for (const value2 of argumentsValue.values) {
|
|
27211
|
+
const size = shellValueByteLength(value2) + 1;
|
|
27212
|
+
if (size > limits.maxArgumentBytes - rawBytes) fail("argument byte limit exceeded");
|
|
27213
|
+
rawBytes += size;
|
|
27214
|
+
}
|
|
27215
|
+
for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
|
|
27216
|
+
}
|
|
27217
|
+
let list = false;
|
|
27218
|
+
let pipe = false;
|
|
27219
|
+
let overwrite = false;
|
|
27220
|
+
let destination2;
|
|
27221
|
+
let archive;
|
|
27222
|
+
let ended = false;
|
|
27223
|
+
const patterns2 = [];
|
|
27224
|
+
for (let index = 0; index < args.length; index++) {
|
|
27225
|
+
const argument2 = args[index];
|
|
27226
|
+
if (!ended && argument2 === "--") {
|
|
27227
|
+
ended = true;
|
|
27228
|
+
continue;
|
|
27229
|
+
}
|
|
27230
|
+
if (!ended && argument2.startsWith("-") && argument2 !== "-") {
|
|
27231
|
+
for (let offset = 1; offset < argument2.length; offset++) {
|
|
27232
|
+
const flag = argument2[offset];
|
|
27233
|
+
if (flag === "l") list = true;
|
|
27234
|
+
else if (flag === "p") pipe = true;
|
|
27235
|
+
else if (flag === "o") overwrite = true;
|
|
27236
|
+
else if (flag === "d") {
|
|
27237
|
+
if (destination2 !== void 0) fail("-d may only be specified once");
|
|
27238
|
+
destination2 = argument2.slice(offset + 1) || args[++index];
|
|
27239
|
+
if (!destination2) fail("must specify directory to which to extract with -d option");
|
|
27240
|
+
checkPath(destination2, limits);
|
|
27241
|
+
break;
|
|
27242
|
+
} else fail(`unsupported option: -${flag}`);
|
|
27243
|
+
}
|
|
27244
|
+
} else if (archive === void 0) archive = argument2;
|
|
27245
|
+
else patterns2.push(argument2);
|
|
27246
|
+
}
|
|
27247
|
+
if (archive === void 0) fail("usage: unzip [-l] [-p] [-o] [-d DIR] ARCHIVE [FILES...]");
|
|
27248
|
+
checkPath(archive, limits);
|
|
27249
|
+
return { list: list && !pipe, pipe, overwrite, destination: destination2, archive, patterns: patterns2 };
|
|
27250
|
+
}
|
|
27251
|
+
function tokenize2(pattern) {
|
|
27252
|
+
const characters = Array.from(pattern);
|
|
27253
|
+
const tokens2 = [];
|
|
27254
|
+
for (let index = 0; index < characters.length; index++) {
|
|
27255
|
+
const character = characters[index];
|
|
27256
|
+
if (character === "*") {
|
|
27257
|
+
if (tokens2.at(-1)?.kind !== "star") tokens2.push({ kind: "star" });
|
|
27258
|
+
} else if (character === "?") tokens2.push({ kind: "any" });
|
|
27259
|
+
else if (character === "\\") {
|
|
27260
|
+
const escaped3 = characters[++index];
|
|
27261
|
+
tokens2.push(escaped3 === void 0 ? { kind: "never" } : { kind: "literal", value: escaped3 });
|
|
27262
|
+
} else if (character === "[") {
|
|
27263
|
+
const negative = characters[index + 1] === "!" || characters[index + 1] === "^";
|
|
27264
|
+
if (negative) index++;
|
|
27265
|
+
const ranges = [];
|
|
27266
|
+
let closed = false;
|
|
27267
|
+
while (++index < characters.length) {
|
|
27268
|
+
let first = characters[index];
|
|
27269
|
+
if (first === "]") {
|
|
27270
|
+
closed = true;
|
|
27271
|
+
break;
|
|
27272
|
+
}
|
|
27273
|
+
if (first === "\\") first = characters[++index] ?? "";
|
|
27274
|
+
let last = first;
|
|
27275
|
+
if (characters[index + 1] === "-" && characters[index + 2] && characters[index + 2] !== "]") {
|
|
27276
|
+
index += 2;
|
|
27277
|
+
last = characters[index];
|
|
27278
|
+
if (last === "\\") last = characters[++index] ?? "";
|
|
27279
|
+
}
|
|
27280
|
+
ranges.push([first.codePointAt(0) ?? -1, last.codePointAt(0) ?? -1]);
|
|
27281
|
+
}
|
|
27282
|
+
tokens2.push(closed ? { kind: "class", ranges, negative } : { kind: "never" });
|
|
27283
|
+
} else tokens2.push({ kind: "literal", value: character });
|
|
27284
|
+
}
|
|
27285
|
+
return tokens2;
|
|
27286
|
+
}
|
|
27287
|
+
var Selection = class {
|
|
27288
|
+
constructor(patterns2, limits, signal) {
|
|
27289
|
+
this.limits = limits;
|
|
27290
|
+
this.signal = signal;
|
|
27291
|
+
this.patterns = patterns2.map(tokenize2);
|
|
27292
|
+
}
|
|
27293
|
+
limits;
|
|
27294
|
+
signal;
|
|
27295
|
+
work = 0;
|
|
27296
|
+
patterns;
|
|
27297
|
+
matched = /* @__PURE__ */ new Set();
|
|
27298
|
+
step() {
|
|
27299
|
+
if (++this.work > this.limits.maxPatternSteps) fail("pattern work limit exceeded");
|
|
27300
|
+
}
|
|
27301
|
+
async matches(name2, firstMatchOnly = false) {
|
|
27302
|
+
if (!this.patterns.length) return true;
|
|
27303
|
+
const characters = Array.from(name2);
|
|
27304
|
+
let selected = false;
|
|
27305
|
+
for (let pattern = 0; pattern < this.patterns.length; pattern++) {
|
|
27306
|
+
this.step();
|
|
27307
|
+
let states = new Uint8Array(characters.length + 1);
|
|
27308
|
+
states[0] = 1;
|
|
27309
|
+
for (const token of this.patterns[pattern]) {
|
|
27310
|
+
const next = new Uint8Array(states.length);
|
|
27311
|
+
for (let index = 0; index < states.length; index++) {
|
|
27312
|
+
this.step();
|
|
27313
|
+
if (token.kind === "star") next[index] = states[index] || (index > 0 ? next[index - 1] : 0);
|
|
27314
|
+
else if (states[index] && index < characters.length) {
|
|
27315
|
+
const character = characters[index];
|
|
27316
|
+
let match = token.kind === "any" || token.kind === "literal" && token.value === character;
|
|
27317
|
+
if (token.kind === "class") {
|
|
27318
|
+
let inRange = false;
|
|
27319
|
+
for (const [first, last] of token.ranges) {
|
|
27320
|
+
this.step();
|
|
27321
|
+
if (character.codePointAt(0) >= first && character.codePointAt(0) <= last) inRange = true;
|
|
27322
|
+
}
|
|
27323
|
+
match = inRange !== token.negative;
|
|
27324
|
+
}
|
|
27325
|
+
if (match) next[index + 1] = 1;
|
|
27326
|
+
}
|
|
27327
|
+
if (this.work % 4096 === 0) await yieldTurn(this.signal);
|
|
27328
|
+
}
|
|
27329
|
+
states = next;
|
|
27330
|
+
}
|
|
27331
|
+
if (states[characters.length]) {
|
|
27332
|
+
this.matched.add(pattern);
|
|
27333
|
+
if (firstMatchOnly) return true;
|
|
27334
|
+
selected = true;
|
|
27335
|
+
}
|
|
27336
|
+
}
|
|
27337
|
+
return selected;
|
|
27338
|
+
}
|
|
27339
|
+
};
|
|
27340
|
+
var Answers = class {
|
|
27341
|
+
constructor(source2, limits, signal) {
|
|
27342
|
+
this.limits = limits;
|
|
27343
|
+
this.signal = signal;
|
|
27344
|
+
this.iterator = readBytes(source2, signal)[Symbol.asyncIterator]();
|
|
27345
|
+
}
|
|
27346
|
+
limits;
|
|
27347
|
+
signal;
|
|
27348
|
+
iterator;
|
|
27349
|
+
chunk = new Uint8Array();
|
|
27350
|
+
offset = 0;
|
|
27351
|
+
bytes = 0;
|
|
27352
|
+
pulls = 0;
|
|
27353
|
+
async read(maximum = 9) {
|
|
27354
|
+
const answer = [];
|
|
27355
|
+
while (answer.length < maximum) {
|
|
27356
|
+
this.signal.throwIfAborted();
|
|
27357
|
+
if (this.offset === this.chunk.length) {
|
|
27358
|
+
if (++this.pulls > this.limits.maxPatternSteps) fail("overwrite input work limit exceeded");
|
|
27359
|
+
if (this.pulls % 64 === 0) await yieldTurn(this.signal);
|
|
27360
|
+
const next = await this.iterator.next();
|
|
27361
|
+
if (next.done) break;
|
|
27362
|
+
if (next.value.length > this.limits.maxFilesFromBytes - this.bytes) fail("overwrite input byte limit exceeded");
|
|
27363
|
+
this.bytes += next.value.length;
|
|
27364
|
+
this.chunk = Uint8Array.from(next.value);
|
|
27365
|
+
this.offset = 0;
|
|
27366
|
+
if (!this.chunk.length) continue;
|
|
27367
|
+
}
|
|
27368
|
+
const byte = this.chunk[this.offset++];
|
|
27369
|
+
answer.push(byte);
|
|
27370
|
+
if (byte === 10) break;
|
|
27371
|
+
}
|
|
27372
|
+
return answer.length ? import_buffer.Buffer.from(answer).toString("utf8") : void 0;
|
|
27373
|
+
}
|
|
27374
|
+
async close() {
|
|
27375
|
+
await this.iterator.return?.();
|
|
27376
|
+
}
|
|
27377
|
+
};
|
|
27378
|
+
|
|
27197
27379
|
// packages/safe-bash/src/commands/archive/zip.ts
|
|
27198
27380
|
var ZipFailure = class extends Error {
|
|
27199
27381
|
constructor(status2, label, detail) {
|
|
@@ -27204,7 +27386,8 @@ var ZipFailure = class extends Error {
|
|
|
27204
27386
|
status;
|
|
27205
27387
|
label;
|
|
27206
27388
|
};
|
|
27207
|
-
function parse12(
|
|
27389
|
+
async function parse12(scope, limits) {
|
|
27390
|
+
const context2 = scope.context;
|
|
27208
27391
|
if (context2.args.length > limits.maxArgumentBytes) fail("argument count limit exceeded");
|
|
27209
27392
|
let bytes3 = 0;
|
|
27210
27393
|
for (const argument2 of context2.args) {
|
|
@@ -27226,20 +27409,49 @@ function parse12(context2, limits) {
|
|
|
27226
27409
|
let recursive = false;
|
|
27227
27410
|
let quiet = false;
|
|
27228
27411
|
let junkPaths = false;
|
|
27412
|
+
let level = 6;
|
|
27413
|
+
let stdinNames = false;
|
|
27229
27414
|
let literal = false;
|
|
27230
27415
|
let firstOperand = -1;
|
|
27231
27416
|
const operands = [];
|
|
27232
|
-
|
|
27417
|
+
const includes = [];
|
|
27418
|
+
const excludes = [];
|
|
27419
|
+
for (let index = 0; index < context2.args.length; index++) {
|
|
27420
|
+
const argument2 = context2.args[index];
|
|
27233
27421
|
checkPath(argument2, limits);
|
|
27234
27422
|
if (!literal && argument2 === "--") {
|
|
27235
27423
|
if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "can't use -- before archive name");
|
|
27236
27424
|
literal = true;
|
|
27237
27425
|
} else if (!literal && argument2.startsWith("-") && argument2 !== "-") {
|
|
27238
|
-
for (
|
|
27426
|
+
for (let offset = 1; offset < argument2.length; offset++) {
|
|
27427
|
+
const flag = argument2[offset];
|
|
27239
27428
|
if (flag === "r") recursive = true;
|
|
27240
27429
|
else if (flag === "q") quiet = true;
|
|
27241
27430
|
else if (flag === "j") junkPaths = true;
|
|
27242
|
-
else
|
|
27431
|
+
else if (flag === "@") stdinNames = true;
|
|
27432
|
+
else if (flag !== void 0 && flag >= "0" && flag <= "9") level = Number(flag);
|
|
27433
|
+
else if (flag === "i" || flag === "x") {
|
|
27434
|
+
const patterns2 = flag === "i" ? includes : excludes;
|
|
27435
|
+
const before = patterns2.length;
|
|
27436
|
+
const append = (pattern) => {
|
|
27437
|
+
checkPath(pattern, limits);
|
|
27438
|
+
if (includes.length + excludes.length >= limits.maxMembers) fail("pattern count limit exceeded");
|
|
27439
|
+
patterns2.push(pattern);
|
|
27440
|
+
};
|
|
27441
|
+
if (offset + 1 < argument2.length) append(argument2.slice(offset + 1));
|
|
27442
|
+
while (index + 1 < context2.args.length) {
|
|
27443
|
+
const next = context2.args[index + 1];
|
|
27444
|
+
if (next === "@") {
|
|
27445
|
+
index++;
|
|
27446
|
+
break;
|
|
27447
|
+
}
|
|
27448
|
+
if (next.startsWith("-") && next !== "-") break;
|
|
27449
|
+
append(next);
|
|
27450
|
+
index++;
|
|
27451
|
+
}
|
|
27452
|
+
if (patterns2.length === before) throw new ZipFailure(16, "Invalid command arguments", `option '${flag}' requires a value`);
|
|
27453
|
+
break;
|
|
27454
|
+
} else throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
|
|
27243
27455
|
}
|
|
27244
27456
|
} else if (archive === void 0) archive = argument2;
|
|
27245
27457
|
else {
|
|
@@ -27248,11 +27460,32 @@ function parse12(context2, limits) {
|
|
|
27248
27460
|
operands.push(argument2);
|
|
27249
27461
|
}
|
|
27250
27462
|
}
|
|
27251
|
-
if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "expected zip [-r] [-q] [-j] ARCHIVE FILES...");
|
|
27463
|
+
if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "expected zip [-r] [-q] [-j] [-@] [-0..-9] ARCHIVE FILES... [-i PATTERNS...] [-x PATTERNS...]");
|
|
27252
27464
|
if (archive === "-" || operands.includes("-")) throw new ZipFailure(16, "Invalid command arguments", "standard input/output archives are unsupported");
|
|
27253
27465
|
if (!archive.slice(archive.lastIndexOf("/") + 1).includes(".")) archive += ".zip";
|
|
27254
27466
|
checkPath(archive, limits);
|
|
27255
|
-
|
|
27467
|
+
const names = [];
|
|
27468
|
+
if (stdinNames) {
|
|
27469
|
+
const input3 = await collectBytes(scope.source(context2.stdin), { maxBytes: limits.maxFilesFromBytes, signal: context2.signal });
|
|
27470
|
+
let start = 0;
|
|
27471
|
+
let lines3 = 0;
|
|
27472
|
+
for (let end = 0; end <= input3.length; end++) {
|
|
27473
|
+
if (end !== input3.length && input3[end] !== 10) continue;
|
|
27474
|
+
if (++lines3 > limits.maxPatternSteps) fail("stdin filename work limit exceeded");
|
|
27475
|
+
if (lines3 % 128 === 0) await yieldTurn(context2.signal);
|
|
27476
|
+
let last = end;
|
|
27477
|
+
while (last > start && input3[last - 1] === 13) last--;
|
|
27478
|
+
if (last > start) {
|
|
27479
|
+
if (names.length + operands.length >= limits.maxMembers) fail("operand limit exceeded");
|
|
27480
|
+
if (last - start > limits.maxPathBytes) fail("path byte limit exceeded");
|
|
27481
|
+
const name2 = text2(input3.subarray(start, last));
|
|
27482
|
+
checkPath(name2, limits);
|
|
27483
|
+
names.push(name2);
|
|
27484
|
+
}
|
|
27485
|
+
start = end + 1;
|
|
27486
|
+
}
|
|
27487
|
+
}
|
|
27488
|
+
return { archive, recursive, quiet, junkPaths, includes, excludes, level, operands: [...names, ...operands], firstOperand };
|
|
27256
27489
|
}
|
|
27257
27490
|
function memberName(path, limits) {
|
|
27258
27491
|
if (path.startsWith("//") && !path.startsWith("///")) fail("UNC source paths are unsupported");
|
|
@@ -27289,6 +27522,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27289
27522
|
}
|
|
27290
27523
|
const old = new Map(archive.entries.map((entry) => [entry.name, entry]));
|
|
27291
27524
|
const selected = /* @__PURE__ */ new Map();
|
|
27525
|
+
const selection = new Selection([...parsed.includes, ...parsed.excludes], limits, context2.signal);
|
|
27292
27526
|
const ancestors = [];
|
|
27293
27527
|
let visits = 0;
|
|
27294
27528
|
let work = 0;
|
|
@@ -27322,9 +27556,18 @@ async function prepare(scope, parsed, budget) {
|
|
|
27322
27556
|
}
|
|
27323
27557
|
if (existing2 && !hasIdentity(stat)) fail("cannot exclude archive aliases when source backing identity is unknown");
|
|
27324
27558
|
const directory2 = stat.type === "directory";
|
|
27325
|
-
if (parsed.junkPaths) name2 = directory2 ? "" : name2.slice(name2.lastIndexOf("/") + 1);
|
|
27326
27559
|
if (directory2 && name2 && !name2.endsWith("/")) name2 += "/";
|
|
27327
|
-
|
|
27560
|
+
selection.matched.clear();
|
|
27561
|
+
await selection.matches(name2);
|
|
27562
|
+
let included = parsed.includes.length === 0;
|
|
27563
|
+
let excluded = false;
|
|
27564
|
+
for (const pattern of selection.matched) {
|
|
27565
|
+
if (pattern < parsed.includes.length) included = true;
|
|
27566
|
+
else excluded = true;
|
|
27567
|
+
}
|
|
27568
|
+
const sourceName = name2;
|
|
27569
|
+
if (parsed.junkPaths) name2 = directory2 ? "" : name2.slice(name2.lastIndexOf("/") + 1);
|
|
27570
|
+
if (name2 && included && !excluded) {
|
|
27328
27571
|
checkPath(name2, limits);
|
|
27329
27572
|
const previous = selected.get(name2);
|
|
27330
27573
|
if (previous && previous.source !== source2) {
|
|
@@ -27341,7 +27584,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27341
27584
|
const current = await scope.operation(() => context2.fs.stat(path, { signal: context2.signal }));
|
|
27342
27585
|
const currentPath = await scope.operation(() => context2.fs.realpath(path, { signal: context2.signal }));
|
|
27343
27586
|
if (currentPath !== canonical || !unchanged4(stat, current)) fail(`source changed while reading: ${source2}`);
|
|
27344
|
-
let entry = await makeZipEntry(name2, bytes4, { modified: new Date(stat.mtimeMs), mode: stat.mode, directory: directory2, symlink: false }, limits, context2.signal);
|
|
27587
|
+
let entry = await makeZipEntry(name2, bytes4, { modified: new Date(stat.mtimeMs), mode: stat.mode, directory: directory2, symlink: false }, limits, context2.signal, parsed.level);
|
|
27345
27588
|
if ([".z", ".zip", ".zoo", ".arc", ".lzh", ".arj"].some((suffix2) => name2.toLowerCase().endsWith(suffix2))) entry = { ...entry, method: 0, data: bytes4 };
|
|
27346
27589
|
const prior = old.get(name2);
|
|
27347
27590
|
if (prior?.comment) entry = { ...entry, comment: prior.comment };
|
|
@@ -27359,7 +27602,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27359
27602
|
for (const child of children) {
|
|
27360
27603
|
if (!child.name || child.name === "." || child.name === ".." || child.name.includes("/") || child.name.includes("\0")) fail("invalid filesystem directory entry");
|
|
27361
27604
|
const prefix3 = source2 === "." ? "" : source2.endsWith("/") ? source2 : `${source2}/`;
|
|
27362
|
-
await visit(`${prefix3}${child.name}`, `${
|
|
27605
|
+
await visit(`${prefix3}${child.name}`, `${sourceName}${child.name}`, depth + 1);
|
|
27363
27606
|
}
|
|
27364
27607
|
} finally {
|
|
27365
27608
|
ancestors.pop();
|
|
@@ -27367,7 +27610,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27367
27610
|
}
|
|
27368
27611
|
};
|
|
27369
27612
|
for (const operand of parsed.operands) await visit(operand, memberName(operand, limits), 0);
|
|
27370
|
-
if (!selected.size) {
|
|
27613
|
+
if (!selected.size && !parsed.includes.length) {
|
|
27371
27614
|
const detail = parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${context2.args.slice(0, parsed.firstOperand).join(" ")} . -i ${context2.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
|
|
27372
27615
|
throw new ZipFailure(12, "Nothing to do!", detail);
|
|
27373
27616
|
}
|
|
@@ -27400,6 +27643,7 @@ async function prepare(scope, parsed, budget) {
|
|
|
27400
27643
|
entries2.push(entry);
|
|
27401
27644
|
append(entry, false);
|
|
27402
27645
|
}
|
|
27646
|
+
if (!entries2.length && !parsed.quiet) await budget.output(" zip warning: zip file empty\n");
|
|
27403
27647
|
const bytes3 = await writeZipArchive({ entries: entries2, comment: archive.comment }, limits, context2.signal);
|
|
27404
27648
|
return { output: output2, parentName, parent, parentStat, existing: existing2, bytes: bytes3, progress };
|
|
27405
27649
|
}
|
|
@@ -27411,7 +27655,7 @@ function createZipCommand(options2 = {}) {
|
|
|
27411
27655
|
const context2 = scope.context;
|
|
27412
27656
|
const budget = new Budget14(context2, limits);
|
|
27413
27657
|
try {
|
|
27414
|
-
const parsed = parse12(
|
|
27658
|
+
const parsed = await parse12(scope, limits);
|
|
27415
27659
|
const prepared = await prepare(scope, parsed, budget);
|
|
27416
27660
|
await writeFileOutput(context2, prepared.bytes, () => scope.operation(() => publishZip(scope, prepared)));
|
|
27417
27661
|
for (const message3 of prepared.progress) await budget.output(message3);
|
|
@@ -27442,188 +27686,6 @@ zip error: ${error.label} (${error.message})
|
|
|
27442
27686
|
// packages/safe-bash/src/commands/archive/unzip.ts
|
|
27443
27687
|
init_platform();
|
|
27444
27688
|
|
|
27445
|
-
// packages/safe-bash/src/commands/archive/unzip/arguments.ts
|
|
27446
|
-
init_platform();
|
|
27447
|
-
function parseArguments(context2, limits) {
|
|
27448
|
-
const { args } = context2;
|
|
27449
|
-
let bytes3 = 0;
|
|
27450
|
-
for (const argument2 of args) {
|
|
27451
|
-
bytes3 += import_buffer.Buffer.byteLength(argument2) + 1;
|
|
27452
|
-
if (bytes3 > limits.maxArgumentBytes) fail("argument byte limit exceeded");
|
|
27453
|
-
if (argument2.includes("\0")) fail("NUL in argument");
|
|
27454
|
-
}
|
|
27455
|
-
if (context2.argumentValues) {
|
|
27456
|
-
const argumentsValue = getCommandArguments(context2);
|
|
27457
|
-
let rawBytes = 0;
|
|
27458
|
-
for (const value2 of argumentsValue.values) {
|
|
27459
|
-
const size = shellValueByteLength(value2) + 1;
|
|
27460
|
-
if (size > limits.maxArgumentBytes - rawBytes) fail("argument byte limit exceeded");
|
|
27461
|
-
rawBytes += size;
|
|
27462
|
-
}
|
|
27463
|
-
for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
|
|
27464
|
-
}
|
|
27465
|
-
let list = false;
|
|
27466
|
-
let pipe = false;
|
|
27467
|
-
let overwrite = false;
|
|
27468
|
-
let destination2;
|
|
27469
|
-
let archive;
|
|
27470
|
-
let ended = false;
|
|
27471
|
-
const patterns2 = [];
|
|
27472
|
-
for (let index = 0; index < args.length; index++) {
|
|
27473
|
-
const argument2 = args[index];
|
|
27474
|
-
if (!ended && argument2 === "--") {
|
|
27475
|
-
ended = true;
|
|
27476
|
-
continue;
|
|
27477
|
-
}
|
|
27478
|
-
if (!ended && argument2.startsWith("-") && argument2 !== "-") {
|
|
27479
|
-
for (let offset = 1; offset < argument2.length; offset++) {
|
|
27480
|
-
const flag = argument2[offset];
|
|
27481
|
-
if (flag === "l") list = true;
|
|
27482
|
-
else if (flag === "p") pipe = true;
|
|
27483
|
-
else if (flag === "o") overwrite = true;
|
|
27484
|
-
else if (flag === "d") {
|
|
27485
|
-
if (destination2 !== void 0) fail("-d may only be specified once");
|
|
27486
|
-
destination2 = argument2.slice(offset + 1) || args[++index];
|
|
27487
|
-
if (!destination2) fail("must specify directory to which to extract with -d option");
|
|
27488
|
-
checkPath(destination2, limits);
|
|
27489
|
-
break;
|
|
27490
|
-
} else fail(`unsupported option: -${flag}`);
|
|
27491
|
-
}
|
|
27492
|
-
} else if (archive === void 0) archive = argument2;
|
|
27493
|
-
else patterns2.push(argument2);
|
|
27494
|
-
}
|
|
27495
|
-
if (archive === void 0) fail("usage: unzip [-l] [-p] [-o] [-d DIR] ARCHIVE [FILES...]");
|
|
27496
|
-
checkPath(archive, limits);
|
|
27497
|
-
return { list: list && !pipe, pipe, overwrite, destination: destination2, archive, patterns: patterns2 };
|
|
27498
|
-
}
|
|
27499
|
-
function tokenize2(pattern) {
|
|
27500
|
-
const characters = Array.from(pattern);
|
|
27501
|
-
const tokens2 = [];
|
|
27502
|
-
for (let index = 0; index < characters.length; index++) {
|
|
27503
|
-
const character = characters[index];
|
|
27504
|
-
if (character === "*") {
|
|
27505
|
-
if (tokens2.at(-1)?.kind !== "star") tokens2.push({ kind: "star" });
|
|
27506
|
-
} else if (character === "?") tokens2.push({ kind: "any" });
|
|
27507
|
-
else if (character === "\\") {
|
|
27508
|
-
const escaped3 = characters[++index];
|
|
27509
|
-
tokens2.push(escaped3 === void 0 ? { kind: "never" } : { kind: "literal", value: escaped3 });
|
|
27510
|
-
} else if (character === "[") {
|
|
27511
|
-
const negative = characters[index + 1] === "!" || characters[index + 1] === "^";
|
|
27512
|
-
if (negative) index++;
|
|
27513
|
-
const ranges = [];
|
|
27514
|
-
let closed = false;
|
|
27515
|
-
while (++index < characters.length) {
|
|
27516
|
-
let first = characters[index];
|
|
27517
|
-
if (first === "]") {
|
|
27518
|
-
closed = true;
|
|
27519
|
-
break;
|
|
27520
|
-
}
|
|
27521
|
-
if (first === "\\") first = characters[++index] ?? "";
|
|
27522
|
-
let last = first;
|
|
27523
|
-
if (characters[index + 1] === "-" && characters[index + 2] && characters[index + 2] !== "]") {
|
|
27524
|
-
index += 2;
|
|
27525
|
-
last = characters[index];
|
|
27526
|
-
if (last === "\\") last = characters[++index] ?? "";
|
|
27527
|
-
}
|
|
27528
|
-
ranges.push([first.codePointAt(0) ?? -1, last.codePointAt(0) ?? -1]);
|
|
27529
|
-
}
|
|
27530
|
-
tokens2.push(closed ? { kind: "class", ranges, negative } : { kind: "never" });
|
|
27531
|
-
} else tokens2.push({ kind: "literal", value: character });
|
|
27532
|
-
}
|
|
27533
|
-
return tokens2;
|
|
27534
|
-
}
|
|
27535
|
-
var Selection = class {
|
|
27536
|
-
constructor(patterns2, limits, signal) {
|
|
27537
|
-
this.limits = limits;
|
|
27538
|
-
this.signal = signal;
|
|
27539
|
-
this.patterns = patterns2.map(tokenize2);
|
|
27540
|
-
}
|
|
27541
|
-
limits;
|
|
27542
|
-
signal;
|
|
27543
|
-
work = 0;
|
|
27544
|
-
patterns;
|
|
27545
|
-
matched = /* @__PURE__ */ new Set();
|
|
27546
|
-
step() {
|
|
27547
|
-
if (++this.work > this.limits.maxPatternSteps) fail("pattern work limit exceeded");
|
|
27548
|
-
}
|
|
27549
|
-
async matches(name2, firstMatchOnly = false) {
|
|
27550
|
-
if (!this.patterns.length) return true;
|
|
27551
|
-
const characters = Array.from(name2);
|
|
27552
|
-
let selected = false;
|
|
27553
|
-
for (let pattern = 0; pattern < this.patterns.length; pattern++) {
|
|
27554
|
-
this.step();
|
|
27555
|
-
let states = new Uint8Array(characters.length + 1);
|
|
27556
|
-
states[0] = 1;
|
|
27557
|
-
for (const token of this.patterns[pattern]) {
|
|
27558
|
-
const next = new Uint8Array(states.length);
|
|
27559
|
-
for (let index = 0; index < states.length; index++) {
|
|
27560
|
-
this.step();
|
|
27561
|
-
if (token.kind === "star") next[index] = states[index] || (index > 0 ? next[index - 1] : 0);
|
|
27562
|
-
else if (states[index] && index < characters.length) {
|
|
27563
|
-
const character = characters[index];
|
|
27564
|
-
let match = token.kind === "any" || token.kind === "literal" && token.value === character;
|
|
27565
|
-
if (token.kind === "class") {
|
|
27566
|
-
let inRange = false;
|
|
27567
|
-
for (const [first, last] of token.ranges) {
|
|
27568
|
-
this.step();
|
|
27569
|
-
if (character.codePointAt(0) >= first && character.codePointAt(0) <= last) inRange = true;
|
|
27570
|
-
}
|
|
27571
|
-
match = inRange !== token.negative;
|
|
27572
|
-
}
|
|
27573
|
-
if (match) next[index + 1] = 1;
|
|
27574
|
-
}
|
|
27575
|
-
if (this.work % 4096 === 0) await yieldTurn(this.signal);
|
|
27576
|
-
}
|
|
27577
|
-
states = next;
|
|
27578
|
-
}
|
|
27579
|
-
if (states[characters.length]) {
|
|
27580
|
-
this.matched.add(pattern);
|
|
27581
|
-
if (firstMatchOnly) return true;
|
|
27582
|
-
selected = true;
|
|
27583
|
-
}
|
|
27584
|
-
}
|
|
27585
|
-
return selected;
|
|
27586
|
-
}
|
|
27587
|
-
};
|
|
27588
|
-
var Answers = class {
|
|
27589
|
-
constructor(source2, limits, signal) {
|
|
27590
|
-
this.limits = limits;
|
|
27591
|
-
this.signal = signal;
|
|
27592
|
-
this.iterator = readBytes(source2, signal)[Symbol.asyncIterator]();
|
|
27593
|
-
}
|
|
27594
|
-
limits;
|
|
27595
|
-
signal;
|
|
27596
|
-
iterator;
|
|
27597
|
-
chunk = new Uint8Array();
|
|
27598
|
-
offset = 0;
|
|
27599
|
-
bytes = 0;
|
|
27600
|
-
pulls = 0;
|
|
27601
|
-
async read(maximum = 9) {
|
|
27602
|
-
const answer = [];
|
|
27603
|
-
while (answer.length < maximum) {
|
|
27604
|
-
this.signal.throwIfAborted();
|
|
27605
|
-
if (this.offset === this.chunk.length) {
|
|
27606
|
-
if (++this.pulls > this.limits.maxPatternSteps) fail("overwrite input work limit exceeded");
|
|
27607
|
-
if (this.pulls % 64 === 0) await yieldTurn(this.signal);
|
|
27608
|
-
const next = await this.iterator.next();
|
|
27609
|
-
if (next.done) break;
|
|
27610
|
-
if (next.value.length > this.limits.maxFilesFromBytes - this.bytes) fail("overwrite input byte limit exceeded");
|
|
27611
|
-
this.bytes += next.value.length;
|
|
27612
|
-
this.chunk = Uint8Array.from(next.value);
|
|
27613
|
-
this.offset = 0;
|
|
27614
|
-
if (!this.chunk.length) continue;
|
|
27615
|
-
}
|
|
27616
|
-
const byte = this.chunk[this.offset++];
|
|
27617
|
-
answer.push(byte);
|
|
27618
|
-
if (byte === 10) break;
|
|
27619
|
-
}
|
|
27620
|
-
return answer.length ? import_buffer.Buffer.from(answer).toString("utf8") : void 0;
|
|
27621
|
-
}
|
|
27622
|
-
async close() {
|
|
27623
|
-
await this.iterator.return?.();
|
|
27624
|
-
}
|
|
27625
|
-
};
|
|
27626
|
-
|
|
27627
27689
|
// packages/safe-bash/src/commands/archive/unzip/safety.ts
|
|
27628
27690
|
init_platform();
|
|
27629
27691
|
import { retainFileSystemCleanup as retainFileSystemCleanup3 } from "@poe-platform/safe-fs/core";
|