@poe-platform/safe-bash 0.1.430 → 0.1.432

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