@poe-platform/safe-js 0.1.119 → 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);
@@ -8524,7 +8529,7 @@ function getRegexMember(target, property, budget) {
8524
8529
  return createSandboxClosure({
8525
8530
  sandbox: true,
8526
8531
  name: `RegExp#${property}`,
8527
- call: (args) => callRegexMethod(target, property, args)
8532
+ call: (args, context) => callRegexMethod(context?.thisValue, property, args, budget, context)
8528
8533
  });
8529
8534
  }
8530
8535
  function escapeRegexSource(source, budget) {
@@ -8552,15 +8557,39 @@ 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
- function callRegexMethod(target, methodName, args) {
8558
- const match = executeRegex(target, String(args[0]));
8559
- return methodName === "test" ? match !== null : toMatchArray(match, String(args[0]));
8562
+ async function callRegexMethod(target, methodName, args, budget, context) {
8563
+ if (target === null || typeof target !== "object" || methodName === "exec" && !isSandboxRegex(target)) {
8564
+ throw new TypeError(`RegExp#${methodName} requires ${methodName === "exec" ? "a regex" : "an object"} receiver.`);
8565
+ }
8566
+ const retained = {};
8567
+ let cursor;
8568
+ budget.setRetainedValues(retained, () => [target, ...args, cursor]);
8569
+ try {
8570
+ const input = await sandboxString(args[0], budget, context);
8571
+ if (methodName === "test") {
8572
+ const exec = context?.getProperty === void 0 ? getSandboxDataProperty(target, "exec", budget) : context.getProperty(target, "exec");
8573
+ if (isSandboxClosure(exec)) {
8574
+ const result = await invokeBuiltinClosure(exec, [input], budget, context, target);
8575
+ if (result !== null && typeof result !== "object") {
8576
+ throw new TypeError("RegExp#test exec must return an object or null.");
8577
+ }
8578
+ return result !== null;
8579
+ }
8580
+ }
8581
+ if (!isSandboxRegex(target)) throw new TypeError("RegExp execution requires a regex receiver.");
8582
+ cursor = target.lastIndex;
8583
+ const lastIndex = await sandboxNumber(cursor, budget, context);
8584
+ const match = executeRegex(target, input, lastIndex);
8585
+ return methodName === "test" ? match !== null : toMatchArray(match, input);
8586
+ } finally {
8587
+ budget.setRetainedValues(retained, void 0);
8588
+ }
8560
8589
  }
8561
- function executeRegex(target, input) {
8590
+ function executeRegex(target, input, lastIndex) {
8562
8591
  const pattern = getSandboxRegexPattern(target);
8563
- const match = matchRegex(pattern, input, target.lastIndex);
8592
+ const match = matchRegex(pattern, input, lastIndex);
8564
8593
  if (pattern.flags.global) {
8565
8594
  target.lastIndex = match === null ? 0 : match.index + match.text.length;
8566
8595
  }
@@ -10484,13 +10513,14 @@ function deepCopyToSandbox(value) {
10484
10513
  seen: /* @__PURE__ */ new WeakMap()
10485
10514
  });
10486
10515
  }
10487
- function cloneSandboxValue(value) {
10516
+ function cloneSandboxValue(value, options = {}) {
10488
10517
  const initializeIterators = [];
10489
10518
  const copy = copyToSandbox(
10490
10519
  value,
10491
10520
  {
10492
10521
  seen: /* @__PURE__ */ new WeakMap(),
10493
- initializeIterators
10522
+ initializeIterators,
10523
+ ...options
10494
10524
  },
10495
10525
  "<root>",
10496
10526
  true
@@ -10589,11 +10619,12 @@ function measureSandboxData(values, options = {}) {
10589
10619
  }
10590
10620
  if (isSandboxPromise(value)) return;
10591
10621
  if (isSandboxRegex(value)) {
10592
- const { source, flags } = captureRegexData(value);
10622
+ const { source, flags, lastIndex } = captureRegexData(value);
10593
10623
  const compiled = regexCompiledData(getSandboxRegexPattern(value));
10594
10624
  const staged = compiled.ticket === void 0 ? 0 : compiled.ticket.owner.budget.compileTicketUsage(compiled.ticket);
10595
10625
  usage += Math.max(6 + source.length + flags.length + compiled.units, staged - 1);
10596
10626
  if (compiled.ticket !== void 0) options.compileTickets?.add(compiled.ticket);
10627
+ visit(lastIndex, depth + 1);
10597
10628
  return;
10598
10629
  }
10599
10630
  if (isSandboxArguments(value)) {
@@ -10674,7 +10705,16 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
10674
10705
  return value;
10675
10706
  }
10676
10707
  if (isLiveCapability(value)) throw new TypeError("Live capabilities require their owning realm bridge.");
10677
- 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)) {
10678
10718
  return value;
10679
10719
  }
10680
10720
  if (isSandboxCollectionIterator(value)) {
@@ -10883,9 +10923,9 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
10883
10923
  if (existing !== void 0) return existing;
10884
10924
  guard.allocate(1 + source.length + flags.length);
10885
10925
  const regex = new RegExp(source, flags);
10886
- regex.lastIndex = lastIndex;
10887
- guard.retainScratch();
10888
10926
  state.seen.set(value, regex);
10927
+ Reflect.set(regex, "lastIndex", copyFromSandbox(lastIndex, state, `${path}.lastIndex`, options, depth + 1));
10928
+ guard.retainScratch();
10889
10929
  return regex;
10890
10930
  } finally {
10891
10931
  guard.close();
@@ -11272,7 +11312,7 @@ function encodeReplayData(value, options = {}) {
11272
11312
  kind: "regex",
11273
11313
  source: entry.source,
11274
11314
  flags: entry.flags,
11275
- lastIndex: entry.lastIndex
11315
+ lastIndex: child(entry.lastIndex, "lastIndex")
11276
11316
  };
11277
11317
  } else if (isSandboxArguments(entry)) {
11278
11318
  nodes[id] = { kind: "arguments", data: serializeArguments(entry, child) };
@@ -11439,11 +11479,12 @@ function decodeReplayData(input, options = {}, parent) {
11439
11479
  return result3;
11440
11480
  }
11441
11481
  if (kind === "regex") {
11442
- 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")) {
11443
11483
  throw new TypeError("Invalid replay regular expression.");
11444
11484
  }
11445
- const result3 = createSandboxRegex(node.source, node.flags, node.lastIndex, compilation);
11485
+ const result3 = createSandboxRegex(node.source, node.flags, 0, compilation);
11446
11486
  restored.set(id, result3);
11487
+ result3.lastIndex = child(own(node, "lastIndex"));
11447
11488
  return result3;
11448
11489
  }
11449
11490
  if (kind === "arguments") {
@@ -25008,7 +25049,11 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
25008
25049
  return budget.allocateString(result + value.slice(spanStart));
25009
25050
  }
25010
25051
  if (methodName === "replace" || methodName === "replaceAll") {
25011
- 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);
25012
25057
  }
25013
25058
  if ((methodName === "match" || methodName === "matchAll" || methodName === "search") && !isSandboxRegex(args[0])) {
25014
25059
  return callStringPattern(value, methodName, args[0], budget, parent, context);
@@ -25123,7 +25168,7 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
25123
25168
  operation.release();
25124
25169
  }
25125
25170
  }
25126
- function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25171
+ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
25127
25172
  const search = args[0];
25128
25173
  const replacement = args[1];
25129
25174
  if (!isSandboxRegex(search) && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
@@ -25141,7 +25186,8 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25141
25186
  replacement,
25142
25187
  methodName === "replaceAll",
25143
25188
  budget,
25144
- callClosure
25189
+ callClosure,
25190
+ context
25145
25191
  );
25146
25192
  }
25147
25193
  if (typeof replacement === "string") {
@@ -25158,20 +25204,28 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25158
25204
  callClosure
25159
25205
  );
25160
25206
  }
25161
- async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure) {
25207
+ async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure, context) {
25162
25208
  if (regex.flags.includes("g")) regex.lastIndex = 0;
25163
- const matches = collectRegexMatches(regex, value, replaceAll || regex.flags.includes("g"));
25164
- let result = "";
25165
- let copiedThrough = 0;
25166
- for (const match of matches) {
25167
- result += value.slice(copiedThrough, match.index);
25168
- result += typeof replacement === "string" ? expandReplacement(replacement, match.text, match.captures, value, match.index) : String(
25169
- await callClosure(replacement, [match.text, ...match.captures, match.index, value])
25170
- );
25171
- 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);
25172
25228
  }
25173
- result += value.slice(copiedThrough);
25174
- return budget.allocateString(result);
25175
25229
  }
25176
25230
  function expandReplacement(replacement, match, captures, input, matchIndex) {
25177
25231
  let result = "";
@@ -25298,35 +25352,51 @@ async function callStringPattern(value, methodName, pattern, budget, parent, con
25298
25352
  operation.release();
25299
25353
  }
25300
25354
  }
25301
- 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) {
25302
25371
  const regex = args[0];
25303
25372
  if (!isSandboxRegex(regex))
25304
25373
  throw new TypeError(`String#${methodName} requires a regex argument.`);
25305
25374
  if (methodName === "search") {
25306
- const lastIndex = regex.lastIndex;
25307
- if (!Object.is(lastIndex, 0)) regex.lastIndex = 0;
25308
- const match = executeRegex(regex, value);
25309
- 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;
25310
25379
  return match?.index ?? -1;
25311
25380
  }
25312
25381
  if (methodName === "matchAll" && !regex.flags.includes("g"))
25313
25382
  throw new TypeError("String#matchAll requires a global regex.");
25314
25383
  if (methodName === "match" && !regex.flags.includes("g"))
25315
- return toMatchArray(executeRegex(regex, value), value);
25384
+ return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
25316
25385
  if (methodName === "match") regex.lastIndex = 0;
25317
- const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, regex.lastIndex, compilation) : regex;
25318
- 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));
25319
25388
  if (methodName === "match" && matches.length === 0) return null;
25320
25389
  return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
25321
25390
  }
25322
- function collectRegexMatches(regex, value, all, budget) {
25391
+ function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
25323
25392
  const matches = [];
25324
25393
  do {
25325
- const match = executeRegex(regex, value);
25394
+ const match = executeRegex(regex, value, lastIndex);
25326
25395
  if (match === null) break;
25327
25396
  budget?.allocateArrayLength(matches.length + 1);
25328
25397
  matches.push(match);
25329
- 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;
25330
25400
  } while (all);
25331
25401
  return matches;
25332
25402
  }
@@ -30657,7 +30727,7 @@ function createMiscGlobals(options) {
30657
30727
  return {
30658
30728
  structuredClone: createSandboxClosure({
30659
30729
  sandbox: true,
30660
- call: ([value]) => structuredCloneSandboxValue(value, options.budget),
30730
+ call: ([value], context) => structuredCloneSandboxValue(value, options.budget, context?.compilation),
30661
30731
  name: "structuredClone"
30662
30732
  }),
30663
30733
  parseInt: createSandboxClosure({
@@ -30682,11 +30752,20 @@ function createMiscGlobals(options) {
30682
30752
  })
30683
30753
  };
30684
30754
  }
30685
- function structuredCloneSandboxValue(value, budget) {
30686
- assertSandboxGraphDepth(value);
30687
- const clone = cloneSandboxValue(value);
30688
- assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
30689
- 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
+ }
30690
30769
  }
30691
30770
  function assertStructuredCloneable(value, seen) {
30692
30771
  if (isSandboxClosure(value) || isSandboxPromise(value) || isSandboxCollectionIterator(value)) {
@@ -33328,4 +33407,4 @@ export {
33328
33407
  FileSnapshotBackend,
33329
33408
  run
33330
33409
  };
33331
- //# sourceMappingURL=chunk-6LFWVA64.js.map
33410
+ //# sourceMappingURL=chunk-7HK37H74.js.map