@poe-platform/safe-bash 0.1.509 → 0.1.511

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.
@@ -1616,9 +1616,24 @@ async function resetDescendants(node, previous, ledger, signal) {
1616
1616
  }
1617
1617
  async function matchEre(program, subject, ledger, signal) {
1618
1618
  ledger.check(signal);
1619
- const root = resolveEreProgram(program, ledger);
1619
+ resolveEreProgram(program, ledger);
1620
+ ledger.admitInput("subjectBytes", subject.length, signal);
1621
+ await admitAscii(subject, ledger, signal);
1622
+ return runMatcher(program, subject, ledger, signal, 0, true);
1623
+ }
1624
+ async function createEreSpanMatcher(program, subject, ledger, signal) {
1625
+ ledger.check(signal);
1626
+ resolveEreProgram(program, ledger);
1620
1627
  ledger.admitInput("subjectBytes", subject.length, signal);
1621
1628
  await admitAscii(subject, ledger, signal);
1629
+ ledger.charge("allocationUnits", 2, signal);
1630
+ return async (start) => {
1631
+ if (!Number.isSafeInteger(start) || start < 0 || start > subject.length) throw new RangeError("Invalid ERE search cursor");
1632
+ return runMatcher(program, subject, ledger, signal, start, false);
1633
+ };
1634
+ }
1635
+ async function runMatcher(program, subject, ledger, signal, from, materialize) {
1636
+ const root = resolveEreProgram(program, ledger);
1622
1637
  const width = program.groups + 1;
1623
1638
  ledger.charge("work", width * 2, signal);
1624
1639
  ledger.charge("allocationUnits", width * 2 + 1, signal);
@@ -1635,7 +1650,7 @@ async function matchEre(program, subject, ledger, signal) {
1635
1650
  ledger.charge("allocationUnits", 5, signal);
1636
1651
  pending.push({ position, task: next, captures, histories });
1637
1652
  };
1638
- for (let start = 0; start <= subject.length; start++) {
1653
+ for (let start = from; start <= subject.length; start++) {
1639
1654
  push(start, task(() => ({ kind: "node", node: root, next: null })), emptyCaptures, emptyHistories);
1640
1655
  let best;
1641
1656
  while (pending.length > 0) {
@@ -1720,6 +1735,11 @@ async function matchEre(program, subject, ledger, signal) {
1720
1735
  }
1721
1736
  }
1722
1737
  if (best) {
1738
+ if (!materialize) {
1739
+ ledger.charge("allocationUnits", 2, signal);
1740
+ ledger.check(signal);
1741
+ return Object.freeze({ start, end: best.position });
1742
+ }
1723
1743
  ledger.charge("captureSlots", width, signal);
1724
1744
  let bytes3 = best.position - start;
1725
1745
  for (let group = 1; group < width; group++) {
@@ -1745,8 +1765,9 @@ async function matchEre(program, subject, ledger, signal) {
1745
1765
  return Object.freeze({ matched: true, captures: Object.freeze(captures), values: Object.freeze(values) });
1746
1766
  }
1747
1767
  }
1748
- ledger.charge("allocationUnits", 3, signal);
1749
1768
  ledger.check(signal);
1769
+ if (!materialize) return void 0;
1770
+ ledger.charge("allocationUnits", 3, signal);
1750
1771
  return Object.freeze({ matched: false, captures: Object.freeze([]), values: Object.freeze([]) });
1751
1772
  }
1752
1773
 
@@ -1760,7 +1781,9 @@ var defaults2 = Object.freeze({
1760
1781
  maxResultBytes: 2048,
1761
1782
  maxWork: 2e6,
1762
1783
  maxAllocationUnits: 1e6,
1763
- maxStates: 65536
1784
+ maxStates: 65536,
1785
+ maxMatchesPerLine: 128,
1786
+ maxTotalMatches: 128
1764
1787
  });
1765
1788
  var ceilings = Object.freeze({
1766
1789
  maxWorkers: 32,
@@ -1771,7 +1794,9 @@ var ceilings = Object.freeze({
1771
1794
  maxResultBytes: 65536,
1772
1795
  maxWork: 33554432,
1773
1796
  maxAllocationUnits: 4e6,
1774
- maxStates: 65536
1797
+ maxStates: 65536,
1798
+ maxMatchesPerLine: 1e5,
1799
+ maxTotalMatches: 1e5
1775
1800
  });
1776
1801
  var typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
1777
1802
  var byteLength = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
@@ -1847,7 +1872,7 @@ function admit(input3, limits, signal) {
1847
1872
  record(row, ["bytes", "all", "terminated"], ["directory", "ancestors"]);
1848
1873
  if (!(row.bytes instanceof Uint8Array) || typeof row.all !== "boolean" || typeof row.terminated !== "boolean" || Object.hasOwn(row, "directory") && typeof row.directory !== "boolean" || Object.hasOwn(row, "ancestors") && typeof row.ancestors !== "boolean") fail("protocol", "invalid row");
1849
1874
  if (Object.hasOwn(row, "directory") || Object.hasOwn(row, "ancestors")) fail("unsupported", "glob row flags are unsupported");
1850
- if (row.all) fail("unsupported", "all-match enumeration is unsupported");
1875
+ if (row.all && selected.kind !== "grep") fail("unsupported", "rg all-match enumeration is unsupported");
1851
1876
  const length = byteLength.call(row.bytes);
1852
1877
  if (length > limits.maxInputBytes - bytes3) fail("limit", "aggregate input byte limit exceeded");
1853
1878
  bytes3 += length;
@@ -1869,9 +1894,9 @@ function admit(input3, limits, signal) {
1869
1894
  const source2 = new Uint8Array(byteBuffer.call(row.bytes), byteOffset.call(row.bytes), byteLength.call(row.bytes));
1870
1895
  const copy2 = new Uint8Array(source2.length);
1871
1896
  copy2.set(source2);
1872
- rows2.push({ bytes: copy2, all: false, terminated: row.terminated });
1897
+ rows2.push({ bytes: copy2, all: row.all, terminated: row.terminated });
1873
1898
  }
1874
- return { id: input3.id, descriptor: ownedDescriptor, rows: rows2, ledger };
1899
+ return { id: input3.id, descriptor: ownedDescriptor, rows: rows2, ledger, limits };
1875
1900
  }
1876
1901
  function admitExpr(input3, limits, signal) {
1877
1902
  signal.throwIfAborted();
@@ -2020,13 +2045,13 @@ async function compileLiteral(bytes3, ledger, signal) {
2020
2045
  }
2021
2046
  return { bytes: bytes3, fallback };
2022
2047
  }
2023
- async function literalStart(program, subject, whole, ledger, signal) {
2048
+ async function literalStart(program, subject, whole, ledger, signal, from = 0) {
2024
2049
  const { bytes: bytes3, fallback } = program;
2025
2050
  ledger.charge("work", 1, signal);
2026
2051
  await ledger.checkpoint(signal);
2027
- if (whole && bytes3.length !== subject.length || bytes3.length > subject.length) return -1;
2028
- if (bytes3.length === 0) return 0;
2029
- for (let index = 0, prefix3 = 0; index < subject.length; ) {
2052
+ if (whole && (from !== 0 || bytes3.length !== subject.length) || bytes3.length > subject.length - from) return -1;
2053
+ if (bytes3.length === 0) return from;
2054
+ for (let index = from, prefix3 = 0; index < subject.length; ) {
2030
2055
  ledger.charge("work", 1, signal);
2031
2056
  if (subject[index] === bytes3[prefix3]) {
2032
2057
  index++;
@@ -2037,15 +2062,63 @@ async function literalStart(program, subject, whole, ledger, signal) {
2037
2062
  }
2038
2063
  return -1;
2039
2064
  }
2065
+ async function enumerate(input3, row, finders, usage2, signal) {
2066
+ const { ledger, limits } = input3;
2067
+ ledger.charge("allocationUnits", finders.length + 2, signal);
2068
+ const cached = new Array(finders.length);
2069
+ const ranges = [];
2070
+ for (let from = 0; from <= row.bytes.length; ) {
2071
+ let best;
2072
+ for (let index = 0; index < finders.length; index++) {
2073
+ ledger.charge("work", 1, signal);
2074
+ await ledger.checkpoint(signal);
2075
+ let candidate = cached[index];
2076
+ if (candidate === void 0 || candidate !== null && candidate.start < from) {
2077
+ candidate = await finders[index](from) ?? null;
2078
+ cached[index] = candidate;
2079
+ }
2080
+ if (candidate && (!best || candidate.start < best.start || candidate.start === best.start && candidate.end > best.end)) best = candidate;
2081
+ }
2082
+ if (!best) break;
2083
+ if (ranges.length / 2 >= limits.maxMatchesPerLine) fail("limit", "matches per line limit exceeded");
2084
+ if (usage2.count >= limits.maxTotalMatches) fail("limit", "total match limit exceeded");
2085
+ if (usage2.count >= Math.floor(limits.maxResultBytes / 16)) fail("limit", "result byte limit exceeded");
2086
+ ledger.charge("work", 2, signal);
2087
+ ledger.charge("allocationUnits", 24, signal);
2088
+ usage2.count++;
2089
+ ranges.push(best.start, best.end);
2090
+ if (best.end > best.start) from = best.end;
2091
+ else {
2092
+ const byte = row.bytes[best.end];
2093
+ from = best.end + (byte === void 0 || byte < 128 ? 1 : byte < 224 ? 2 : byte < 240 ? 3 : 4);
2094
+ }
2095
+ }
2096
+ ledger.charge("work", ranges.length, signal);
2097
+ await ledger.checkpoint(signal);
2098
+ return new Float64Array(ranges);
2099
+ }
2040
2100
  async function executeLiteral(input3, signal) {
2041
2101
  const { descriptor: selected, rows: rows2, ledger } = input3;
2042
2102
  const programs2 = [];
2043
2103
  for (const pattern of selected.patterns) {
2044
2104
  programs2.push(await compileLiteral(await literalBytes(pattern, selected, ledger, signal), ledger, signal));
2045
2105
  }
2106
+ ledger.charge("allocationUnits", 3, signal);
2046
2107
  const results = [];
2108
+ const usage2 = { count: 0 };
2047
2109
  for (const row of rows2) {
2048
2110
  await validateUtf8(row.bytes, ledger, signal);
2111
+ if (row.all) {
2112
+ ledger.charge("allocationUnits", programs2.length * 2, signal);
2113
+ const finders = programs2.map((program) => async (from) => {
2114
+ const start2 = await literalStart(program, row.bytes, selected.whole, ledger, signal, from);
2115
+ if (start2 < 0) return void 0;
2116
+ ledger.charge("allocationUnits", 2, signal);
2117
+ return { start: start2, end: start2 + program.bytes.length };
2118
+ });
2119
+ results.push(await enumerate(input3, row, finders, usage2, signal));
2120
+ continue;
2121
+ }
2049
2122
  let start = -1;
2050
2123
  let end = -1;
2051
2124
  for (const program of programs2) {
@@ -2058,6 +2131,10 @@ async function executeLiteral(input3, signal) {
2058
2131
  if (selected.kind === "grep") break;
2059
2132
  }
2060
2133
  signal.throwIfAborted();
2134
+ if (start >= 0) {
2135
+ if (usage2.count >= input3.limits.maxTotalMatches || usage2.count >= Math.floor(input3.limits.maxResultBytes / 16)) fail("limit", "total match or result byte limit exceeded");
2136
+ usage2.count++;
2137
+ }
2061
2138
  results.push(start < 0 ? new Float64Array() : new Float64Array([start, end]));
2062
2139
  }
2063
2140
  return { id: input3.id, results };
@@ -2073,7 +2150,9 @@ async function execute(input3, signal) {
2073
2150
  const fragments = selected.whole ? [{ text: "^(", literal: false }, { text: pattern, literal: selected.fixed }, { text: ")$", literal: false }] : [{ text: pattern, literal: selected.fixed }];
2074
2151
  programs2.push(await compileEre(fragments, ledger, signal));
2075
2152
  }
2153
+ ledger.charge("allocationUnits", 3, signal);
2076
2154
  const results = [];
2155
+ const usage2 = { count: 0 };
2077
2156
  for (const row of rows2) {
2078
2157
  ledger.charge("allocationUnits", row.bytes.length * 2 + 2, signal);
2079
2158
  const characters = [];
@@ -2084,6 +2163,13 @@ async function execute(input3, signal) {
2084
2163
  await ledger.checkpoint(signal);
2085
2164
  }
2086
2165
  const subject = characters.join("");
2166
+ if (row.all) {
2167
+ ledger.charge("allocationUnits", programs2.length + 1, signal);
2168
+ const finders = [];
2169
+ for (const program of programs2) finders.push(await createEreSpanMatcher(program, subject, ledger, signal));
2170
+ results.push(await enumerate(input3, row, finders, usage2, signal));
2171
+ continue;
2172
+ }
2087
2173
  let span;
2088
2174
  for (const program of programs2) {
2089
2175
  const match = await matchEre(program, subject, ledger, signal);
@@ -2096,6 +2182,10 @@ async function execute(input3, signal) {
2096
2182
  if (!span || candidate.start < span.start) span = candidate;
2097
2183
  }
2098
2184
  signal.throwIfAborted();
2185
+ if (span) {
2186
+ if (usage2.count >= input3.limits.maxTotalMatches || usage2.count >= Math.floor(input3.limits.maxResultBytes / 16)) fail("limit", "total match or result byte limit exceeded");
2187
+ usage2.count++;
2188
+ }
2099
2189
  results.push(span ? new Float64Array([span.start, span.end]) : new Float64Array());
2100
2190
  }
2101
2191
  return { id: input3.id, results };
@@ -10792,6 +10882,7 @@ function createGrepCommands(executor) {
10792
10882
  const maxCount = value(parsed, "m") === void 0 ? Infinity : integer(value(parsed, "m"));
10793
10883
  const batchSize = Number.isFinite(maxCount) || parsed.flags.has("q") || parsed.flags.has("l") || parsed.flags.has("L") ? 1 : 128;
10794
10884
  const delimiter = parsed.flags.has("z") ? "\0" : "\n";
10885
+ const extractMatches = parsed.flags.has("o") && !["c", "q", "l", "L", "v"].some((flag) => parsed.flags.has(flag));
10795
10886
  let anySelected = false;
10796
10887
  let failed = false;
10797
10888
  for (const name2 of names) {
@@ -10803,7 +10894,7 @@ function createGrepCommands(executor) {
10803
10894
  const available2 = new AvailableRecords(parsed.flags.has("z") ? 0 : 10, bufferLimit);
10804
10895
  const source2 = name2 === "-" ? input(context2) : requiredFileInput(context2, grepRequirements, "file", name2, bufferLimit);
10805
10896
  records: if (maxCount > 0) for await (const batch of available2.batches(lines(available2.source(source2), parsed.flags.has("z") ? 0 : 10), (line) => line.bytes.length, () => batchSize)) {
10806
- const results = await session.run(descriptor2, batch.map((line) => ({ bytes: line.bytes, all: parsed.flags.has("o"), terminated: line.terminated })));
10897
+ const results = await session.run(descriptor2, batch.map((line) => ({ bytes: line.bytes, all: extractMatches, terminated: line.terminated })));
10807
10898
  for (let index = 0; index < batch.length; index++) {
10808
10899
  const line = batch[index];
10809
10900
  context2.signal.throwIfAborted();