@poe-platform/safe-bash 0.1.431 → 0.1.433

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.
@@ -7127,7 +7127,7 @@ var characterClasses = {
7127
7127
  async function tokens(pattern, work) {
7128
7128
  const admission = stringCheckpoint(work, pattern.length);
7129
7129
  if (admission) await admission;
7130
- work.allocation?.reserve(128 + pattern.length * 64, 0);
7130
+ const reservation = work.allocation?.reserve(128 + pattern.length * 64, 0);
7131
7131
  const result2 = [];
7132
7132
  const characters = Array.from(pattern);
7133
7133
  const lastClosingBracket = characters.lastIndexOf("]");
@@ -7190,15 +7190,20 @@ async function tokens(pattern, work) {
7190
7190
  } else result2.push({ kind: "literal", value: character });
7191
7191
  } else result2.push({ kind: "literal", value: character });
7192
7192
  }
7193
- return result2;
7193
+ return { patternTokens: result2, reservation };
7194
7194
  }
7195
7195
  async function compilePattern(pattern, work) {
7196
7196
  work.signal.throwIfAborted();
7197
- const patternTokens = await tokens(pattern, work);
7197
+ const { patternTokens } = await tokens(pattern, work);
7198
7198
  return (value2, start = 0, end = value2.length) => matchTokens(patternTokens, value2, work, start, end);
7199
7199
  }
7200
7200
  async function matchesPattern(pattern, value2, work) {
7201
- return (await compilePattern(pattern, work))(value2);
7201
+ const { patternTokens, reservation } = await tokens(pattern, work);
7202
+ try {
7203
+ return await matchTokens(patternTokens, value2, work, 0, value2.length);
7204
+ } finally {
7205
+ reservation?.release();
7206
+ }
7202
7207
  }
7203
7208
  async function matchTokens(patternTokens, value2, work, start, end) {
7204
7209
  work.signal.throwIfAborted();
@@ -8453,6 +8458,14 @@ var ValueArena = class {
8453
8458
  this.#records.add(record4);
8454
8459
  return record4;
8455
8460
  }
8461
+ grow(record4, bytes3) {
8462
+ this.assertOpen();
8463
+ if (!this.#records.has(record4) || record4.object) throw new Error("Shell value reservation cannot grow");
8464
+ if (!Number.isSafeInteger(bytes3) || bytes3 < 0) throw new RangeError("Invalid shell value allocation");
8465
+ if (bytes3 > this.maximumBytes - this.#bytes) this.fail("maxExpansionBytes");
8466
+ record4.bytes += bytes3;
8467
+ this.#bytes += bytes3;
8468
+ }
8456
8469
  commit(record4, object2) {
8457
8470
  this.assertOpen();
8458
8471
  if (!this.#records.has(record4) || record4.object || this.#objects.has(object2)) throw new Error("Shell value reservation is not fresh");
@@ -8523,10 +8536,17 @@ var ValueScope = class {
8523
8536
  #holds = /* @__PURE__ */ new Map();
8524
8537
  #closed = false;
8525
8538
  #enrollment;
8539
+ #bytesReservation;
8526
8540
  assertOpen() {
8527
8541
  this.arena.assertOpen();
8528
8542
  if (this.#closed) throw new Error("Shell value scope is closed");
8529
8543
  }
8544
+ reserveBytes(bytes3) {
8545
+ this.assertOpen();
8546
+ this.#enrollment ??= this.arena.allocate(64, 1);
8547
+ if (this.#bytesReservation) this.arena.grow(this.#bytesReservation, bytes3);
8548
+ else this.#bytesReservation = this.arena.allocate(bytes3, 0);
8549
+ }
8530
8550
  reserve(bytes3, slots) {
8531
8551
  this.assertOpen();
8532
8552
  this.#enrollment ??= this.arena.allocate(64, 1);
@@ -8581,6 +8601,7 @@ var ValueScope = class {
8581
8601
  if (this.#closed) return;
8582
8602
  this.#closed = true;
8583
8603
  for (const release of this.#releases) release();
8604
+ if (this.#bytesReservation) this.arena.release(this.#bytesReservation);
8584
8605
  if (this.#enrollment) this.arena.release(this.#enrollment);
8585
8606
  }
8586
8607
  };
@@ -8699,7 +8720,7 @@ async function* expandBraces(word, budget, signal) {
8699
8720
  };
8700
8721
  const admit2 = (bytes3 = 64) => {
8701
8722
  budget.parsing.admit();
8702
- allocation.reserve(bytes3, 0);
8723
+ allocation.reserveBytes(bytes3);
8703
8724
  };
8704
8725
  const sum = (left, right, limit) => {
8705
8726
  if (right > budget.limits[limit] - left) budget.fail(limit);
@@ -8860,7 +8881,7 @@ async function* expandBraces(word, budget, signal) {
8860
8881
  await checkpoint();
8861
8882
  const materialized = budget.values.scope();
8862
8883
  try {
8863
- materialized.reserve(64, 0);
8884
+ materialized.reserveBytes(64);
8864
8885
  const parts2 = [];
8865
8886
  const generatedSyntax = /* @__PURE__ */ new WeakSet();
8866
8887
  const pending = [{ node: root, rank: rank2 }];
@@ -8869,7 +8890,7 @@ async function* expandBraces(word, budget, signal) {
8869
8890
  const current = pending.pop();
8870
8891
  const node = current.node;
8871
8892
  if (node.kind === "product") {
8872
- materialized.reserve(node.children.length * 32, 0);
8893
+ materialized.reserveBytes(node.children.length * 32);
8873
8894
  let divisor = 1;
8874
8895
  for (let index = node.children.length - 1; index >= 0; index--) {
8875
8896
  await checkpoint();
@@ -8882,30 +8903,30 @@ async function* expandBraces(word, budget, signal) {
8882
8903
  for (const child of node.children) {
8883
8904
  await checkpoint();
8884
8905
  if (choice < child.count) {
8885
- materialized.reserve(32, 0);
8906
+ materialized.reserveBytes(32);
8886
8907
  pending.push({ node: child, rank: choice });
8887
8908
  break;
8888
8909
  }
8889
8910
  choice -= child.count;
8890
8911
  }
8891
8912
  } else {
8892
- materialized.reserve(64, 0);
8913
+ materialized.reserveBytes(64);
8893
8914
  let part;
8894
8915
  if (node.kind === "part") part = node.part;
8895
8916
  else {
8896
8917
  const value2 = node.start + BigInt(current.rank) * node.step;
8897
- materialized.reserve(Math.max(node.width, 32) * 2, 0);
8918
+ materialized.reserveBytes(Math.max(node.width, 32) * 2);
8898
8919
  const digits = node.numeric ? (value2 < 0n ? -value2 : value2).toString() : String.fromCharCode(Number(value2));
8899
8920
  const text3 = node.numeric ? (value2 < 0n ? "-" : "") + digits.padStart(node.width - Number(value2 < 0n), "0") : digits;
8900
8921
  part = { kind: "text", value: text3, quoted: false };
8901
8922
  if (!node.numeric && (text3 === "\\" || text3 === "`")) {
8902
- materialized.reserve(32, 0);
8923
+ materialized.reserveBytes(32);
8903
8924
  generatedSyntax.add(part);
8904
8925
  }
8905
8926
  }
8906
8927
  const previous = parts2.at(-1);
8907
8928
  if (part.kind === "text" && !part.quoted && !part.byteValue && !generatedSyntax.has(part) && previous?.kind === "text" && !previous.quoted && !previous.byteValue && !generatedSyntax.has(previous)) {
8908
- materialized.reserve((previous.value.length + part.value.length) * 2, 0);
8929
+ materialized.reserveBytes((previous.value.length + part.value.length) * 2);
8909
8930
  parts2[parts2.length - 1] = { kind: "text", value: previous.value + part.value, quoted: false };
8910
8931
  } else parts2.push(part);
8911
8932
  }
@@ -8914,7 +8935,7 @@ async function* expandBraces(word, budget, signal) {
8914
8935
  await checkpoint();
8915
8936
  const part = parts2[index];
8916
8937
  if (!generatedSyntax.has(part) || part.kind !== "text") continue;
8917
- materialized.reserve(128, 0);
8938
+ materialized.reserveBytes(128);
8918
8939
  const fragments = [];
8919
8940
  const opaque = /* @__PURE__ */ new Map();
8920
8941
  let length = 0;
@@ -8922,24 +8943,24 @@ async function* expandBraces(word, budget, signal) {
8922
8943
  await checkpoint();
8923
8944
  const current = parts2[position];
8924
8945
  const spelling2 = expansionSpellings.get(current);
8925
- materialized.reserve(32, 0);
8946
+ materialized.reserveBytes(32);
8926
8947
  let fragment;
8927
8948
  if (current.kind === "text" && current.byteValue) {
8928
- materialized.reserve(64, 0);
8949
+ materialized.reserveBytes(64);
8929
8950
  opaque.set(length + 1, current.byteValue);
8930
8951
  fragment = "'\0'";
8931
8952
  } else if (current.kind === "text" && spelling2?.ansi) {
8932
- materialized.reserve(current.value.length * 8 + 4, 0);
8953
+ materialized.reserveBytes(current.value.length * 8 + 4);
8933
8954
  fragment = "'" + current.value.replaceAll("'", "'\\''") + "'";
8934
8955
  } else if (spelling2 && (current.kind !== "text" || current.quoted)) {
8935
- materialized.reserve((spelling2.end - spelling2.start) * 2, 0);
8956
+ materialized.reserveBytes((spelling2.end - spelling2.start) * 2);
8936
8957
  fragment = spelling2.source.slice(spelling2.start, spelling2.end);
8937
8958
  } else if (current.kind === "text") fragment = current.value;
8938
8959
  else throw new BraceExpansionFailure("Missing lexical provenance in brace expansion");
8939
8960
  length = sum(length, fragment.length, "maxExpansionBytes");
8940
8961
  fragments.push(fragment);
8941
8962
  }
8942
- materialized.reserve(length * 2, 0);
8963
+ materialized.reserveBytes(length * 2);
8943
8964
  let replayed;
8944
8965
  try {
8945
8966
  replayed = parseBraceWord(fragments.join(""), opaque, budget.parsing);
@@ -8947,7 +8968,7 @@ async function* expandBraces(word, budget, signal) {
8947
8968
  if (!(error instanceof ShellSyntaxError)) throw error;
8948
8969
  throw new BraceExpansionFailure(error.reason);
8949
8970
  }
8950
- materialized.reserve(replayed.parts.length * 32, 0);
8971
+ materialized.reserveBytes(replayed.parts.length * 32);
8951
8972
  parts2.length = index;
8952
8973
  for (const replayedPart of replayed.parts) parts2.push(replayedPart);
8953
8974
  break;
@@ -13642,7 +13663,7 @@ var Runtime = class _Runtime {
13642
13663
  cwd: state.cwd,
13643
13664
  signal: this.signal,
13644
13665
  locale: state.variables.LC_ALL || state.variables.LC_COLLATE || state.variables.LANG || "C",
13645
- work: { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") },
13666
+ work: { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes"), allocation },
13646
13667
  expand: async (word, pattern = false) => (await this.word(word, state, io, false, pattern, false, pattern)).join(""),
13647
13668
  regex: (subject, pattern) => this.ere(subject, pattern, state, io),
13648
13669
  option: (name2) => name2 === "braceexpand" ? state.braceexpand !== false : name2 === "errexit" ? !!state.errexit : name2 === "nounset" ? !!state.nounset : name2 === "pipefail" ? state.pipefail : false,
@@ -13726,7 +13747,7 @@ var Runtime = class _Runtime {
13726
13747
  }
13727
13748
  if (command7.kind === "case") {
13728
13749
  const subject = (await this.word(command7.subject, state, io, false)).join("");
13729
- const work = { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
13750
+ const work = { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes"), allocation };
13730
13751
  let status4 = 0;
13731
13752
  let fallthrough = false;
13732
13753
  let patterns2 = 0;
@@ -17056,21 +17077,27 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
17056
17077
  const literal = segment2.replace(/\\(.)/gu, "$1");
17057
17078
  for (const candidate of candidates) addCandidate(`${candidate}${candidate && candidate !== "/" ? "/" : ""}${literal}`);
17058
17079
  } else {
17059
- const matches3 = await compilePattern(segment2, work);
17060
- for (const candidate of candidates) {
17061
- let entries2;
17062
- try {
17063
- const pending = this.fs.readdir(resolvePath(state.cwd, candidate || "."), { signal: this.signal });
17064
- entries2 = arrayStore(state) ? await interruptible(pending, this.signal) : await pending;
17065
- } catch (error) {
17066
- if (["ENOENT", "ENOTDIR", "EACCES"].includes(errorCode(error) ?? "")) continue;
17067
- throw error;
17068
- }
17069
- for (const entry of entries2) {
17070
- if (entry.name !== "." && entry.name !== ".." && (state.dotglob || !entry.name.startsWith(".") || segment2.startsWith(".")) && await matches3(entry.name)) {
17071
- addCandidate(`${candidate}${candidate && candidate !== "/" ? "/" : ""}${entry.name}`);
17080
+ const scratch = this.budget.values.scope();
17081
+ work.allocation = scratch;
17082
+ try {
17083
+ const matches3 = await compilePattern(segment2, work);
17084
+ for (const candidate of candidates) {
17085
+ let entries2;
17086
+ try {
17087
+ const pending = this.fs.readdir(resolvePath(state.cwd, candidate || "."), { signal: this.signal });
17088
+ entries2 = arrayStore(state) ? await interruptible(pending, this.signal) : await pending;
17089
+ } catch (error) {
17090
+ if (["ENOENT", "ENOTDIR", "EACCES"].includes(errorCode(error) ?? "")) continue;
17091
+ throw error;
17092
+ }
17093
+ for (const entry of entries2) {
17094
+ if (entry.name !== "." && entry.name !== ".." && (state.dotglob || !entry.name.startsWith(".") || segment2.startsWith(".")) && await matches3(entry.name)) {
17095
+ addCandidate(`${candidate}${candidate && candidate !== "/" ? "/" : ""}${entry.name}`);
17096
+ }
17072
17097
  }
17073
17098
  }
17099
+ } finally {
17100
+ scratch.close();
17074
17101
  }
17075
17102
  }
17076
17103
  candidates = next;