@poe-platform/safe-js 0.1.120 → 0.1.122

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.
@@ -27,7 +27,7 @@ import {
27
27
  validateMigrationSemantics,
28
28
  validateSnapshotData,
29
29
  validateSnapshotMigration
30
- } from "./chunk-XI33TU4X.js";
30
+ } from "./chunk-OZTC4BT3.js";
31
31
 
32
32
  // packages/safe-js/src/migrate.ts
33
33
  import { createHash } from "node:crypto";
@@ -8245,4 +8245,4 @@ export {
8245
8245
  parseMcpConfig,
8246
8246
  makeMcpModule
8247
8247
  };
8248
- //# sourceMappingURL=chunk-XEFVZTJ7.js.map
8248
+ //# sourceMappingURL=chunk-MQSVO6I2.js.map
@@ -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);
@@ -8508,6 +8513,16 @@ function isLineTerminator(character) {
8508
8513
 
8509
8514
  // packages/safe-js/src/interp/methods/regex.ts
8510
8515
  var regexMethodNames = /* @__PURE__ */ new Set(["exec", "test"]);
8516
+ var regexFlagProperties = {
8517
+ hasIndices: "d",
8518
+ global: "g",
8519
+ ignoreCase: "i",
8520
+ multiline: "m",
8521
+ dotAll: "s",
8522
+ unicode: "u",
8523
+ unicodeSets: "v",
8524
+ sticky: "y"
8525
+ };
8511
8526
  function isRegexMethodName(property) {
8512
8527
  return typeof property === "string" && regexMethodNames.has(property);
8513
8528
  }
@@ -8518,6 +8533,7 @@ function getRegexMember(target, property, budget) {
8518
8533
  return budget === void 0 ? flags : budget.allocateString(flags);
8519
8534
  }
8520
8535
  if (property === "lastIndex") return target.lastIndex;
8536
+ if (Object.hasOwn(regexFlagProperties, property)) return target.flags.includes(regexFlagProperties[property]);
8521
8537
  if (!isRegexMethodName(property)) {
8522
8538
  return void 0;
8523
8539
  }
@@ -8552,14 +8568,15 @@ function setRegexMember(target, property, value) {
8552
8568
  if (property !== "lastIndex") {
8553
8569
  throw new TypeError(`RegExp#${String(property)} is not writable.`);
8554
8570
  }
8555
- target.lastIndex = Number(value);
8571
+ target.lastIndex = value;
8556
8572
  }
8557
8573
  async function callRegexMethod(target, methodName, args, budget, context) {
8558
8574
  if (target === null || typeof target !== "object" || methodName === "exec" && !isSandboxRegex(target)) {
8559
8575
  throw new TypeError(`RegExp#${methodName} requires ${methodName === "exec" ? "a regex" : "an object"} receiver.`);
8560
8576
  }
8561
8577
  const retained = {};
8562
- budget.setRetainedValues(retained, () => [target, ...args]);
8578
+ let cursor;
8579
+ budget.setRetainedValues(retained, () => [target, ...args, cursor]);
8563
8580
  try {
8564
8581
  const input = await sandboxString(args[0], budget, context);
8565
8582
  if (methodName === "test") {
@@ -8573,15 +8590,17 @@ async function callRegexMethod(target, methodName, args, budget, context) {
8573
8590
  }
8574
8591
  }
8575
8592
  if (!isSandboxRegex(target)) throw new TypeError("RegExp execution requires a regex receiver.");
8576
- const match = executeRegex(target, input);
8593
+ cursor = target.lastIndex;
8594
+ const lastIndex = await sandboxNumber(cursor, budget, context);
8595
+ const match = executeRegex(target, input, lastIndex);
8577
8596
  return methodName === "test" ? match !== null : toMatchArray(match, input);
8578
8597
  } finally {
8579
8598
  budget.setRetainedValues(retained, void 0);
8580
8599
  }
8581
8600
  }
8582
- function executeRegex(target, input) {
8601
+ function executeRegex(target, input, lastIndex) {
8583
8602
  const pattern = getSandboxRegexPattern(target);
8584
- const match = matchRegex(pattern, input, target.lastIndex);
8603
+ const match = matchRegex(pattern, input, lastIndex);
8585
8604
  if (pattern.flags.global) {
8586
8605
  target.lastIndex = match === null ? 0 : match.index + match.text.length;
8587
8606
  }
@@ -10505,13 +10524,14 @@ function deepCopyToSandbox(value) {
10505
10524
  seen: /* @__PURE__ */ new WeakMap()
10506
10525
  });
10507
10526
  }
10508
- function cloneSandboxValue(value) {
10527
+ function cloneSandboxValue(value, options = {}) {
10509
10528
  const initializeIterators = [];
10510
10529
  const copy = copyToSandbox(
10511
10530
  value,
10512
10531
  {
10513
10532
  seen: /* @__PURE__ */ new WeakMap(),
10514
- initializeIterators
10533
+ initializeIterators,
10534
+ ...options
10515
10535
  },
10516
10536
  "<root>",
10517
10537
  true
@@ -10610,11 +10630,12 @@ function measureSandboxData(values, options = {}) {
10610
10630
  }
10611
10631
  if (isSandboxPromise(value)) return;
10612
10632
  if (isSandboxRegex(value)) {
10613
- const { source, flags } = captureRegexData(value);
10633
+ const { source, flags, lastIndex } = captureRegexData(value);
10614
10634
  const compiled = regexCompiledData(getSandboxRegexPattern(value));
10615
10635
  const staged = compiled.ticket === void 0 ? 0 : compiled.ticket.owner.budget.compileTicketUsage(compiled.ticket);
10616
10636
  usage += Math.max(6 + source.length + flags.length + compiled.units, staged - 1);
10617
10637
  if (compiled.ticket !== void 0) options.compileTickets?.add(compiled.ticket);
10638
+ visit(lastIndex, depth + 1);
10618
10639
  return;
10619
10640
  }
10620
10641
  if (isSandboxArguments(value)) {
@@ -10695,7 +10716,16 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
10695
10716
  return value;
10696
10717
  }
10697
10718
  if (isLiveCapability(value)) throw new TypeError("Live capabilities require their owning realm bridge.");
10698
- if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxRegex(value) || isSandboxPromise(value)) {
10719
+ if (isSandboxRegex(value)) {
10720
+ if (!cloneSandboxCollections) return value;
10721
+ const existing = state.seen.get(value);
10722
+ if (existing !== void 0) return existing;
10723
+ const copy = createSandboxRegex(value.source, value.flags, 0, state.compilation);
10724
+ state.seen.set(value, copy);
10725
+ if (!state.resetRegexLastIndex) copy.lastIndex = copyToSandbox(value.lastIndex, state, `${path}.lastIndex`, true, depth + 1);
10726
+ return copy;
10727
+ }
10728
+ if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxPromise(value)) {
10699
10729
  return value;
10700
10730
  }
10701
10731
  if (isSandboxCollectionIterator(value)) {
@@ -10904,9 +10934,9 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
10904
10934
  if (existing !== void 0) return existing;
10905
10935
  guard.allocate(1 + source.length + flags.length);
10906
10936
  const regex = new RegExp(source, flags);
10907
- regex.lastIndex = lastIndex;
10908
- guard.retainScratch();
10909
10937
  state.seen.set(value, regex);
10938
+ Reflect.set(regex, "lastIndex", copyFromSandbox(lastIndex, state, `${path}.lastIndex`, options, depth + 1));
10939
+ guard.retainScratch();
10910
10940
  return regex;
10911
10941
  } finally {
10912
10942
  guard.close();
@@ -11293,7 +11323,7 @@ function encodeReplayData(value, options = {}) {
11293
11323
  kind: "regex",
11294
11324
  source: entry.source,
11295
11325
  flags: entry.flags,
11296
- lastIndex: entry.lastIndex
11326
+ lastIndex: child(entry.lastIndex, "lastIndex")
11297
11327
  };
11298
11328
  } else if (isSandboxArguments(entry)) {
11299
11329
  nodes[id] = { kind: "arguments", data: serializeArguments(entry, child) };
@@ -11460,11 +11490,12 @@ function decodeReplayData(input, options = {}, parent) {
11460
11490
  return result3;
11461
11491
  }
11462
11492
  if (kind === "regex") {
11463
- if (typeof node.source !== "string" || typeof node.flags !== "string" || typeof node.lastIndex !== "number" || !Number.isFinite(node.lastIndex)) {
11493
+ if (typeof node.source !== "string" || typeof node.flags !== "string" || !Object.hasOwn(node, "lastIndex")) {
11464
11494
  throw new TypeError("Invalid replay regular expression.");
11465
11495
  }
11466
- const result3 = createSandboxRegex(node.source, node.flags, node.lastIndex, compilation);
11496
+ const result3 = createSandboxRegex(node.source, node.flags, 0, compilation);
11467
11497
  restored.set(id, result3);
11498
+ result3.lastIndex = child(own(node, "lastIndex"));
11468
11499
  return result3;
11469
11500
  }
11470
11501
  if (kind === "arguments") {
@@ -25029,7 +25060,11 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
25029
25060
  return budget.allocateString(result + value.slice(spanStart));
25030
25061
  }
25031
25062
  if (methodName === "replace" || methodName === "replaceAll") {
25032
- return callReplaceLikeMethod(value, methodName, args, budget, callClosure);
25063
+ return callReplaceLikeMethod(value, methodName, args, budget, callClosure, context);
25064
+ }
25065
+ const regex = args[0];
25066
+ if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll" && regex.flags.includes("g"))) {
25067
+ return callStringRegexCursor(value, methodName, regex, budget, parent, context);
25033
25068
  }
25034
25069
  if ((methodName === "match" || methodName === "matchAll" || methodName === "search") && !isSandboxRegex(args[0])) {
25035
25070
  return callStringPattern(value, methodName, args[0], budget, parent, context);
@@ -25144,7 +25179,7 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
25144
25179
  operation.release();
25145
25180
  }
25146
25181
  }
25147
- function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25182
+ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
25148
25183
  const search = args[0];
25149
25184
  const replacement = args[1];
25150
25185
  if (!isSandboxRegex(search) && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
@@ -25162,7 +25197,8 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25162
25197
  replacement,
25163
25198
  methodName === "replaceAll",
25164
25199
  budget,
25165
- callClosure
25200
+ callClosure,
25201
+ context
25166
25202
  );
25167
25203
  }
25168
25204
  if (typeof replacement === "string") {
@@ -25179,20 +25215,28 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
25179
25215
  callClosure
25180
25216
  );
25181
25217
  }
25182
- async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure) {
25218
+ async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure, context) {
25183
25219
  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;
25220
+ const cursor = regex.lastIndex;
25221
+ const retained = {};
25222
+ budget.setRetainedValues(retained, () => [regex, cursor, replacement]);
25223
+ try {
25224
+ const lastIndex = await sandboxNumber(cursor, budget, context);
25225
+ const matches = collectRegexMatches(regex, value, replaceAll || regex.flags.includes("g"), void 0, lastIndex);
25226
+ let result = "";
25227
+ let copiedThrough = 0;
25228
+ for (const match of matches) {
25229
+ result += value.slice(copiedThrough, match.index);
25230
+ result += typeof replacement === "string" ? expandReplacement(replacement, match.text, match.captures, value, match.index) : String(
25231
+ await callClosure(replacement, [match.text, ...match.captures, match.index, value])
25232
+ );
25233
+ copiedThrough = match.index + match.text.length;
25234
+ }
25235
+ result += value.slice(copiedThrough);
25236
+ return budget.allocateString(result);
25237
+ } finally {
25238
+ budget.setRetainedValues(retained, void 0);
25193
25239
  }
25194
- result += value.slice(copiedThrough);
25195
- return budget.allocateString(result);
25196
25240
  }
25197
25241
  function expandReplacement(replacement, match, captures, input, matchIndex) {
25198
25242
  let result = "";
@@ -25319,35 +25363,51 @@ async function callStringPattern(value, methodName, pattern, budget, parent, con
25319
25363
  operation.release();
25320
25364
  }
25321
25365
  }
25322
- function callMatchLikeMethod(value, methodName, args, compilation) {
25366
+ async function callStringRegexCursor(value, methodName, regex, budget, parent, context) {
25367
+ const operation = budget.acquireCompileOwner(false, parent?.owner);
25368
+ const compilation = new CompileScope(operation.owner);
25369
+ const cursor = regex.lastIndex;
25370
+ const retained = {};
25371
+ budget.setRetainedValues(retained, () => [regex, cursor]);
25372
+ try {
25373
+ const lastIndex = await sandboxNumber(cursor, budget, context);
25374
+ return callMatchLikeMethod(value, methodName, [regex], compilation, lastIndex);
25375
+ } finally {
25376
+ budget.setRetainedValues(retained, void 0);
25377
+ compilation.dispose();
25378
+ operation.release();
25379
+ }
25380
+ }
25381
+ function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
25323
25382
  const regex = args[0];
25324
25383
  if (!isSandboxRegex(regex))
25325
25384
  throw new TypeError(`String#${methodName} requires a regex argument.`);
25326
25385
  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;
25386
+ const lastIndex2 = regex.lastIndex;
25387
+ if (!Object.is(lastIndex2, 0)) regex.lastIndex = 0;
25388
+ const match = executeRegex(regex, value, 0);
25389
+ if (!Object.is(regex.lastIndex, lastIndex2)) regex.lastIndex = lastIndex2;
25331
25390
  return match?.index ?? -1;
25332
25391
  }
25333
25392
  if (methodName === "matchAll" && !regex.flags.includes("g"))
25334
25393
  throw new TypeError("String#matchAll requires a global regex.");
25335
25394
  if (methodName === "match" && !regex.flags.includes("g"))
25336
- return toMatchArray(executeRegex(regex, value), value);
25395
+ return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
25337
25396
  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);
25397
+ const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, normalizeLastIndex(lastIndex ?? Number(regex.lastIndex)), compilation) : regex;
25398
+ const matches = collectRegexMatches(matcher, value, true, compilation.owner?.budget, Number(matcher.lastIndex));
25340
25399
  if (methodName === "match" && matches.length === 0) return null;
25341
25400
  return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
25342
25401
  }
25343
- function collectRegexMatches(regex, value, all, budget) {
25402
+ function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
25344
25403
  const matches = [];
25345
25404
  do {
25346
- const match = executeRegex(regex, value);
25405
+ const match = executeRegex(regex, value, lastIndex);
25347
25406
  if (match === null) break;
25348
25407
  budget?.allocateArrayLength(matches.length + 1);
25349
25408
  matches.push(match);
25350
- if (all && match.text.length === 0) regex.lastIndex += 1;
25409
+ lastIndex = match.index + match.text.length;
25410
+ if (all && match.text.length === 0) regex.lastIndex = ++lastIndex;
25351
25411
  } while (all);
25352
25412
  return matches;
25353
25413
  }
@@ -30678,7 +30738,7 @@ function createMiscGlobals(options) {
30678
30738
  return {
30679
30739
  structuredClone: createSandboxClosure({
30680
30740
  sandbox: true,
30681
- call: ([value]) => structuredCloneSandboxValue(value, options.budget),
30741
+ call: ([value], context) => structuredCloneSandboxValue(value, options.budget, context?.compilation),
30682
30742
  name: "structuredClone"
30683
30743
  }),
30684
30744
  parseInt: createSandboxClosure({
@@ -30703,11 +30763,20 @@ function createMiscGlobals(options) {
30703
30763
  })
30704
30764
  };
30705
30765
  }
30706
- function structuredCloneSandboxValue(value, budget) {
30707
- assertSandboxGraphDepth(value);
30708
- const clone = cloneSandboxValue(value);
30709
- assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
30710
- return allocateProducedSandboxValue(clone, budget);
30766
+ function structuredCloneSandboxValue(value, budget, parent) {
30767
+ const operation = budget.acquireCompileOwner(false, parent?.owner);
30768
+ const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
30769
+ try {
30770
+ const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
30771
+ assertSandboxGraphDepth(clone);
30772
+ assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
30773
+ allocateProducedSandboxValue(clone, budget);
30774
+ if (compilation !== parent) reconcileCompiledValues(budget, [clone], compilation);
30775
+ return clone;
30776
+ } finally {
30777
+ if (compilation !== parent) compilation.dispose();
30778
+ operation.release();
30779
+ }
30711
30780
  }
30712
30781
  function assertStructuredCloneable(value, seen) {
30713
30782
  if (isSandboxClosure(value) || isSandboxPromise(value) || isSandboxCollectionIterator(value)) {
@@ -33349,4 +33418,4 @@ export {
33349
33418
  FileSnapshotBackend,
33350
33419
  run
33351
33420
  };
33352
- //# sourceMappingURL=chunk-XI33TU4X.js.map
33421
+ //# sourceMappingURL=chunk-OZTC4BT3.js.map