@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.
@@ -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(context2, limits) {
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
- for (const [index, argument2] of context2.args.entries()) {
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 (const flag of argument2.slice(1)) {
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 throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
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
- return { archive, recursive, quiet, junkPaths, operands, firstOperand };
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
- if (name2) {
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}`, `${name2}${child.name}`, depth + 1);
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(context2, limits);
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";