@poe-platform/safe-js 0.1.120 → 0.1.121

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.
@@ -7623,7 +7623,7 @@ function validateTaggedValue(record2, path, state) {
7623
7623
  case "undefined":
7624
7624
  return;
7625
7625
  case "number":
7626
- if (!["-Infinity", "Infinity", "NaN"].includes(String(record2.value))) {
7626
+ if (!["-Infinity", "Infinity", "NaN", "-0"].includes(String(record2.value))) {
7627
7627
  fail("invalidValue", `${path}.value`, "unknown non-finite number value");
7628
7628
  }
7629
7629
  return;
@@ -7645,6 +7645,11 @@ function validateTaggedValue(record2, path, state) {
7645
7645
  requireString(record2.flags, `${path}.flags`, state.limits);
7646
7646
  requireSafeInteger(record2.lastIndex, `${path}.lastIndex`, 0);
7647
7647
  return;
7648
+ case "regex-object":
7649
+ requireString(record2.source, `${path}.source`, state.limits);
7650
+ requireString(record2.flags, `${path}.flags`, state.limits);
7651
+ if (!Object.hasOwn(record2, "lastIndex")) fail("invalidValue", `${path}.lastIndex`, "missing regex cursor");
7652
+ return;
7648
7653
  case "array":
7649
7654
  case "arguments":
7650
7655
  case "object":
@@ -8472,10 +8477,10 @@ function charge(context) {
8472
8477
  allocateRegexSteps(context.steps);
8473
8478
  }
8474
8479
  function normalizeLastIndex(lastIndex) {
8475
- if (!Number.isFinite(lastIndex) || lastIndex <= 0) {
8480
+ if (Number.isNaN(lastIndex) || lastIndex <= 0) {
8476
8481
  return 0;
8477
8482
  }
8478
- return Math.floor(lastIndex);
8483
+ return Math.min(Math.floor(lastIndex), Number.MAX_SAFE_INTEGER);
8479
8484
  }
8480
8485
  function charactersEqual(left, right, ignoreCase) {
8481
8486
  return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
@@ -8552,14 +8557,15 @@ function setRegexMember(target, property, value) {
8552
8557
  if (property !== "lastIndex") {
8553
8558
  throw new TypeError(`RegExp#${String(property)} is not writable.`);
8554
8559
  }
8555
- target.lastIndex = Number(value);
8560
+ target.lastIndex = value;
8556
8561
  }
8557
8562
  async function callRegexMethod(target, methodName, args, budget, context) {
8558
8563
  if (target === null || typeof target !== "object" || methodName === "exec" && !isSandboxRegex(target)) {
8559
8564
  throw new TypeError(`RegExp#${methodName} requires ${methodName === "exec" ? "a regex" : "an object"} receiver.`);
8560
8565
  }
8561
8566
  const retained = {};
8562
- budget.setRetainedValues(retained, () => [target, ...args]);
8567
+ let cursor;
8568
+ budget.setRetainedValues(retained, () => [target, ...args, cursor]);
8563
8569
  try {
8564
8570
  const input = await sandboxString(args[0], budget, context);
8565
8571
  if (methodName === "test") {
@@ -8573,15 +8579,17 @@ async function callRegexMethod(target, methodName, args, budget, context) {
8573
8579
  }
8574
8580
  }
8575
8581
  if (!isSandboxRegex(target)) throw new TypeError("RegExp execution requires a regex receiver.");
8576
- const match = executeRegex(target, input);
8582
+ cursor = target.lastIndex;
8583
+ const lastIndex = await sandboxNumber(cursor, budget, context);
8584
+ const match = executeRegex(target, input, lastIndex);
8577
8585
  return methodName === "test" ? match !== null : toMatchArray(match, input);
8578
8586
  } finally {
8579
8587
  budget.setRetainedValues(retained, void 0);
8580
8588
  }
8581
8589
  }
8582
- function executeRegex(target, input) {
8590
+ function executeRegex(target, input, lastIndex) {
8583
8591
  const pattern = getSandboxRegexPattern(target);
8584
- const match = matchRegex(pattern, input, target.lastIndex);
8592
+ const match = matchRegex(pattern, input, lastIndex);
8585
8593
  if (pattern.flags.global) {
8586
8594
  target.lastIndex = match === null ? 0 : match.index + match.text.length;
8587
8595
  }
@@ -10505,13 +10513,14 @@ function deepCopyToSandbox(value) {
10505
10513
  seen: /* @__PURE__ */ new WeakMap()
10506
10514
  });
10507
10515
  }
10508
- function cloneSandboxValue(value) {
10516
+ function cloneSandboxValue(value, options = {}) {
10509
10517
  const initializeIterators = [];
10510
10518
  const copy = copyToSandbox(
10511
10519
  value,
10512
10520
  {
10513
10521
  seen: /* @__PURE__ */ new WeakMap(),
10514
- initializeIterators
10522
+ initializeIterators,
10523
+ ...options
10515
10524
  },
10516
10525
  "<root>",
10517
10526
  true
@@ -10610,11 +10619,12 @@ function measureSandboxData(values, options = {}) {
10610
10619
  }
10611
10620
  if (isSandboxPromise(value)) return;
10612
10621
  if (isSandboxRegex(value)) {
10613
- const { source, flags } = captureRegexData(value);
10622
+ const { source, flags, lastIndex } = captureRegexData(value);
10614
10623
  const compiled = regexCompiledData(getSandboxRegexPattern(value));
10615
10624
  const staged = compiled.ticket === void 0 ? 0 : compiled.ticket.owner.budget.compileTicketUsage(compiled.ticket);
10616
10625
  usage += Math.max(6 + source.length + flags.length + compiled.units, staged - 1);
10617
10626
  if (compiled.ticket !== void 0) options.compileTickets?.add(compiled.ticket);
10627
+ visit(lastIndex, depth + 1);
10618
10628
  return;
10619
10629
  }
10620
10630
  if (isSandboxArguments(value)) {
@@ -10695,7 +10705,16 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
10695
10705
  return value;
10696
10706
  }
10697
10707
  if (isLiveCapability(value)) throw new TypeError("Live capabilities require their owning realm bridge.");
10698
- if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxRegex(value) || isSandboxPromise(value)) {
10708
+ if (isSandboxRegex(value)) {
10709
+ if (!cloneSandboxCollections) return value;
10710
+ const existing = state.seen.get(value);
10711
+ if (existing !== void 0) return existing;
10712
+ const copy = createSandboxRegex(value.source, value.flags, 0, state.compilation);
10713
+ state.seen.set(value, copy);
10714
+ if (!state.resetRegexLastIndex) copy.lastIndex = copyToSandbox(value.lastIndex, state, `${path}.lastIndex`, true, depth + 1);
10715
+ return copy;
10716
+ }
10717
+ if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxPromise(value)) {
10699
10718
  return value;
10700
10719
  }
10701
10720
  if (isSandboxCollectionIterator(value)) {
@@ -10904,9 +10923,9 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
10904
10923
  if (existing !== void 0) return existing;
10905
10924
  guard.allocate(1 + source.length + flags.length);
10906
10925
  const regex = new RegExp(source, flags);
10907
- regex.lastIndex = lastIndex;
10908
- guard.retainScratch();
10909
10926
  state.seen.set(value, regex);
10927
+ Reflect.set(regex, "lastIndex", copyFromSandbox(lastIndex, state, `${path}.lastIndex`, options, depth + 1));
10928
+ guard.retainScratch();
10910
10929
  return regex;
10911
10930
  } finally {
10912
10931
  guard.close();
@@ -11293,7 +11312,7 @@ function encodeReplayData(value, options = {}) {
11293
11312
  kind: "regex",
11294
11313
  source: entry.source,
11295
11314
  flags: entry.flags,
11296
- lastIndex: entry.lastIndex
11315
+ lastIndex: child(entry.lastIndex, "lastIndex")
11297
11316
  };
11298
11317
  } else if (isSandboxArguments(entry)) {
11299
11318
  nodes[id] = { kind: "arguments", data: serializeArguments(entry, child) };
@@ -11460,11 +11479,12 @@ function decodeReplayData(input, options = {}, parent) {
11460
11479
  return result3;
11461
11480
  }
11462
11481
  if (kind === "regex") {
11463
- if (typeof node.source !== "string" || typeof node.flags !== "string" || typeof node.lastIndex !== "number" || !Number.isFinite(node.lastIndex)) {
11482
+ if (typeof node.source !== "string" || typeof node.flags !== "string" || !Object.hasOwn(node, "lastIndex")) {
11464
11483
  throw new TypeError("Invalid replay regular expression.");
11465
11484
  }
11466
- const result3 = createSandboxRegex(node.source, node.flags, node.lastIndex, compilation);
11485
+ const result3 = createSandboxRegex(node.source, node.flags, 0, compilation);
11467
11486
  restored.set(id, result3);
11487
+ result3.lastIndex = child(own(node, "lastIndex"));
11468
11488
  return result3;
11469
11489
  }
11470
11490
  if (kind === "arguments") {
@@ -25029,7 +25049,11 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
25029
25049
  return budget.allocateString(result + value.slice(spanStart));
25030
25050
  }
25031
25051
  if (methodName === "replace" || methodName === "replaceAll") {
25032
- return callReplaceLikeMethod(value, methodName, args, budget, callClosure);
25052
+ return callReplaceLikeMethod(value, methodName, args, budget, callClosure, context);
25053
+ }
25054
+ const regex = args[0];
25055
+ if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll" && regex.flags.includes("g"))) {
25056
+ return callStringRegexCursor(value, methodName, regex, budget, parent, context);
25033
25057
  }
25034
25058
  if ((methodName === "match" || methodName === "matchAll" || methodName === "search") && !isSandboxRegex(args[0])) {
25035
25059
  return callStringPattern(value, methodName, args[0], budget, parent, context);
@@ -25144,7 +25168,7 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
25144
25168
  operation.release();
25145
25169
  }
25146
25170
  }
25147
- function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25171
+ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
25148
25172
  const search = args[0];
25149
25173
  const replacement = args[1];
25150
25174
  if (!isSandboxRegex(search) && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
@@ -25162,7 +25186,8 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25162
25186
  replacement,
25163
25187
  methodName === "replaceAll",
25164
25188
  budget,
25165
- callClosure
25189
+ callClosure,
25190
+ context
25166
25191
  );
25167
25192
  }
25168
25193
  if (typeof replacement === "string") {
@@ -25179,20 +25204,28 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25179
25204
  callClosure
25180
25205
  );
25181
25206
  }
25182
- async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure) {
25207
+ async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure, context) {
25183
25208
  if (regex.flags.includes("g")) regex.lastIndex = 0;
25184
- const matches = collectRegexMatches(regex, value, replaceAll || regex.flags.includes("g"));
25185
- let result = "";
25186
- let copiedThrough = 0;
25187
- for (const match of matches) {
25188
- result += value.slice(copiedThrough, match.index);
25189
- result += typeof replacement === "string" ? expandReplacement(replacement, match.text, match.captures, value, match.index) : String(
25190
- await callClosure(replacement, [match.text, ...match.captures, match.index, value])
25191
- );
25192
- copiedThrough = match.index + match.text.length;
25209
+ const cursor = regex.lastIndex;
25210
+ const retained = {};
25211
+ budget.setRetainedValues(retained, () => [regex, cursor, replacement]);
25212
+ try {
25213
+ const lastIndex = await sandboxNumber(cursor, budget, context);
25214
+ const matches = collectRegexMatches(regex, value, replaceAll || regex.flags.includes("g"), void 0, lastIndex);
25215
+ let result = "";
25216
+ let copiedThrough = 0;
25217
+ for (const match of matches) {
25218
+ result += value.slice(copiedThrough, match.index);
25219
+ result += typeof replacement === "string" ? expandReplacement(replacement, match.text, match.captures, value, match.index) : String(
25220
+ await callClosure(replacement, [match.text, ...match.captures, match.index, value])
25221
+ );
25222
+ copiedThrough = match.index + match.text.length;
25223
+ }
25224
+ result += value.slice(copiedThrough);
25225
+ return budget.allocateString(result);
25226
+ } finally {
25227
+ budget.setRetainedValues(retained, void 0);
25193
25228
  }
25194
- result += value.slice(copiedThrough);
25195
- return budget.allocateString(result);
25196
25229
  }
25197
25230
  function expandReplacement(replacement, match, captures, input, matchIndex) {
25198
25231
  let result = "";
@@ -25319,35 +25352,51 @@ async function callStringPattern(value, methodName, pattern, budget, parent, con
25319
25352
  operation.release();
25320
25353
  }
25321
25354
  }
25322
- function callMatchLikeMethod(value, methodName, args, compilation) {
25355
+ async function callStringRegexCursor(value, methodName, regex, budget, parent, context) {
25356
+ const operation = budget.acquireCompileOwner(false, parent?.owner);
25357
+ const compilation = new CompileScope(operation.owner);
25358
+ const cursor = regex.lastIndex;
25359
+ const retained = {};
25360
+ budget.setRetainedValues(retained, () => [regex, cursor]);
25361
+ try {
25362
+ const lastIndex = await sandboxNumber(cursor, budget, context);
25363
+ return callMatchLikeMethod(value, methodName, [regex], compilation, lastIndex);
25364
+ } finally {
25365
+ budget.setRetainedValues(retained, void 0);
25366
+ compilation.dispose();
25367
+ operation.release();
25368
+ }
25369
+ }
25370
+ function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
25323
25371
  const regex = args[0];
25324
25372
  if (!isSandboxRegex(regex))
25325
25373
  throw new TypeError(`String#${methodName} requires a regex argument.`);
25326
25374
  if (methodName === "search") {
25327
- const lastIndex = regex.lastIndex;
25328
- if (!Object.is(lastIndex, 0)) regex.lastIndex = 0;
25329
- const match = executeRegex(regex, value);
25330
- if (!Object.is(regex.lastIndex, lastIndex)) regex.lastIndex = lastIndex;
25375
+ const lastIndex2 = regex.lastIndex;
25376
+ if (!Object.is(lastIndex2, 0)) regex.lastIndex = 0;
25377
+ const match = executeRegex(regex, value, 0);
25378
+ if (!Object.is(regex.lastIndex, lastIndex2)) regex.lastIndex = lastIndex2;
25331
25379
  return match?.index ?? -1;
25332
25380
  }
25333
25381
  if (methodName === "matchAll" && !regex.flags.includes("g"))
25334
25382
  throw new TypeError("String#matchAll requires a global regex.");
25335
25383
  if (methodName === "match" && !regex.flags.includes("g"))
25336
- return toMatchArray(executeRegex(regex, value), value);
25384
+ return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
25337
25385
  if (methodName === "match") regex.lastIndex = 0;
25338
- const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, regex.lastIndex, compilation) : regex;
25339
- const matches = collectRegexMatches(matcher, value, true, compilation.owner?.budget);
25386
+ const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, normalizeLastIndex(lastIndex ?? Number(regex.lastIndex)), compilation) : regex;
25387
+ const matches = collectRegexMatches(matcher, value, true, compilation.owner?.budget, Number(matcher.lastIndex));
25340
25388
  if (methodName === "match" && matches.length === 0) return null;
25341
25389
  return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
25342
25390
  }
25343
- function collectRegexMatches(regex, value, all, budget) {
25391
+ function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
25344
25392
  const matches = [];
25345
25393
  do {
25346
- const match = executeRegex(regex, value);
25394
+ const match = executeRegex(regex, value, lastIndex);
25347
25395
  if (match === null) break;
25348
25396
  budget?.allocateArrayLength(matches.length + 1);
25349
25397
  matches.push(match);
25350
- if (all && match.text.length === 0) regex.lastIndex += 1;
25398
+ lastIndex = match.index + match.text.length;
25399
+ if (all && match.text.length === 0) regex.lastIndex = ++lastIndex;
25351
25400
  } while (all);
25352
25401
  return matches;
25353
25402
  }
@@ -30678,7 +30727,7 @@ function createMiscGlobals(options) {
30678
30727
  return {
30679
30728
  structuredClone: createSandboxClosure({
30680
30729
  sandbox: true,
30681
- call: ([value]) => structuredCloneSandboxValue(value, options.budget),
30730
+ call: ([value], context) => structuredCloneSandboxValue(value, options.budget, context?.compilation),
30682
30731
  name: "structuredClone"
30683
30732
  }),
30684
30733
  parseInt: createSandboxClosure({
@@ -30703,11 +30752,20 @@ function createMiscGlobals(options) {
30703
30752
  })
30704
30753
  };
30705
30754
  }
30706
- function structuredCloneSandboxValue(value, budget) {
30707
- assertSandboxGraphDepth(value);
30708
- const clone = cloneSandboxValue(value);
30709
- assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
30710
- return allocateProducedSandboxValue(clone, budget);
30755
+ function structuredCloneSandboxValue(value, budget, parent) {
30756
+ const operation = budget.acquireCompileOwner(false, parent?.owner);
30757
+ const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
30758
+ try {
30759
+ const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
30760
+ assertSandboxGraphDepth(clone);
30761
+ assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
30762
+ allocateProducedSandboxValue(clone, budget);
30763
+ if (compilation !== parent) reconcileCompiledValues(budget, [clone], compilation);
30764
+ return clone;
30765
+ } finally {
30766
+ if (compilation !== parent) compilation.dispose();
30767
+ operation.release();
30768
+ }
30711
30769
  }
30712
30770
  function assertStructuredCloneable(value, seen) {
30713
30771
  if (isSandboxClosure(value) || isSandboxPromise(value) || isSandboxCollectionIterator(value)) {
@@ -33349,4 +33407,4 @@ export {
33349
33407
  FileSnapshotBackend,
33350
33408
  run
33351
33409
  };
33352
- //# sourceMappingURL=chunk-XI33TU4X.js.map
33410
+ //# sourceMappingURL=chunk-7HK37H74.js.map