@poe-platform/safe-js 0.1.114 → 0.1.115

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.
@@ -23827,6 +23827,7 @@ function hoistVarDeclarations(node, scope) {
23827
23827
  }
23828
23828
 
23829
23829
  // packages/safe-js/src/interp/methods/array.ts
23830
+ var arrayLikeSources = /* @__PURE__ */ new WeakMap();
23830
23831
  var activeArrayCallbacks = /* @__PURE__ */ new WeakMap();
23831
23832
  var arrayMethodNames = /* @__PURE__ */ new Set([
23832
23833
  "map",
@@ -23878,7 +23879,7 @@ function getArrayMember(value, property, options) {
23878
23879
  return createSandboxClosure({
23879
23880
  sandbox: true,
23880
23881
  name: `Array#${property}`,
23881
- call: (args, context) => callArrayMethod(value, property, args, options, context?.stack ?? [])
23882
+ call: (args, context) => callArrayMethod(context?.thisValue, property, args, { ...options, context }, context?.stack ?? [])
23882
23883
  });
23883
23884
  }
23884
23885
  return void 0;
@@ -23893,28 +23894,75 @@ function getArrayIndex(property) {
23893
23894
  function isArrayMethodName(property) {
23894
23895
  return typeof property === "string" && arrayMethodNames.has(property);
23895
23896
  }
23896
- async function callArrayMethod(value, methodName, args, options, stack = []) {
23897
- if (isMutatingArrayMethod(methodName)) {
23898
- assertCollectionMutable(value);
23899
- }
23900
- if (isCallbackArrayMethod(methodName)) {
23901
- let callbackState = activeArrayCallbacks.get(value);
23902
- if (callbackState === void 0) {
23903
- callbackState = { depth: 0, leave: enterRunningState(value) };
23904
- activeArrayCallbacks.set(value, callbackState);
23897
+ async function callArrayMethod(receiver, methodName, args, options, stack = []) {
23898
+ if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
23899
+ if (typeof receiver !== "object") throw new TypeError("Object primitive boxing is not supported.");
23900
+ const retainedReceiver = {};
23901
+ options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
23902
+ try {
23903
+ const value = Array.isArray(receiver) || methodName === "concat" ? receiver : await arrayLikeView(receiver, options);
23904
+ if (isMutatingArrayMethod(methodName)) {
23905
+ assertCollectionMutable(receiver);
23905
23906
  }
23906
- callbackState.depth += 1;
23907
- try {
23908
- return await callArrayMethodUnlocked(value, methodName, args, options, stack);
23909
- } finally {
23910
- callbackState.depth -= 1;
23911
- if (callbackState.depth === 0) {
23912
- activeArrayCallbacks.delete(value);
23913
- callbackState.leave();
23907
+ if (isCallbackArrayMethod(methodName)) {
23908
+ let callbackState = activeArrayCallbacks.get(receiver);
23909
+ if (callbackState === void 0) {
23910
+ callbackState = { depth: 0, leave: enterRunningState(receiver) };
23911
+ activeArrayCallbacks.set(receiver, callbackState);
23912
+ }
23913
+ callbackState.depth += 1;
23914
+ try {
23915
+ const result2 = await callArrayMethodUnlocked(value, methodName, args, options, stack);
23916
+ return result2 === value ? receiver : result2;
23917
+ } finally {
23918
+ callbackState.depth -= 1;
23919
+ if (callbackState.depth === 0) {
23920
+ activeArrayCallbacks.delete(receiver);
23921
+ callbackState.leave();
23922
+ }
23914
23923
  }
23915
23924
  }
23925
+ const result = await callArrayMethodUnlocked(value, methodName, args, options, stack);
23926
+ return result === value ? receiver : result;
23927
+ } finally {
23928
+ options.budget.setRetainedValues(retainedReceiver, void 0);
23916
23929
  }
23917
- return callArrayMethodUnlocked(value, methodName, args, options, stack);
23930
+ }
23931
+ async function arrayLikeView(receiver, options) {
23932
+ const rawLength = options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
23933
+ const number = await sandboxNumber(rawLength, options.budget, options.context);
23934
+ const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
23935
+ const view = new Proxy(/* @__PURE__ */ Object.create(null), {
23936
+ get: (_target, key) => {
23937
+ options.budget.visitNode();
23938
+ if (key === "length") return length;
23939
+ if (typeof key !== "string") return void 0;
23940
+ return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, key) : getSandboxDataProperty(receiver, key, options.budget);
23941
+ },
23942
+ has: (_target, key) => {
23943
+ options.budget.visitNode();
23944
+ if (typeof key === "string" && options.hasProperty !== void 0) return options.hasProperty(receiver, key);
23945
+ for (let current = receiver; current !== null; current = getSandboxPrototype(current, options.budget)) {
23946
+ options.budget.visitNode();
23947
+ if (Object.hasOwn(current, key)) return true;
23948
+ }
23949
+ return false;
23950
+ },
23951
+ set: (_target, key, entry) => {
23952
+ options.budget.visitNode();
23953
+ if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
23954
+ if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
23955
+ else if (!Reflect.set(receiver, key, entry)) throw new TypeError(`Cannot assign property '${key}'.`);
23956
+ return true;
23957
+ },
23958
+ deleteProperty: (_target, key) => {
23959
+ options.budget.visitNode();
23960
+ if (typeof key === "string" && options.deleteProperty !== void 0) return options.deleteProperty(receiver, key);
23961
+ return Reflect.deleteProperty(receiver, key);
23962
+ }
23963
+ });
23964
+ arrayLikeSources.set(view, receiver);
23965
+ return view;
23918
23966
  }
23919
23967
  async function callArrayMethodUnlocked(value, methodName, args, options, stack) {
23920
23968
  switch (methodName) {
@@ -24027,11 +24075,21 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24027
24075
  return Reflect.apply(Array.prototype.lastIndexOf, value, [...args]);
24028
24076
  case "join":
24029
24077
  return options.budget.allocateString(Reflect.apply(Array.prototype.join, value, [...args]));
24030
- case "slice":
24031
- return budgetProducedValue(
24032
- Reflect.apply(Array.prototype.slice, value, [...args]),
24033
- options.budget
24034
- );
24078
+ case "slice": {
24079
+ const length = value.length;
24080
+ const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
24081
+ const end = args[1] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
24082
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
24083
+ const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
24084
+ const count = Math.max(final - first, 0);
24085
+ options.budget.allocateArrayLength(count);
24086
+ const result = new Array(count);
24087
+ for (let index = 0; index < count; index += 1) {
24088
+ options.budget.visitNode();
24089
+ if (first + index in value) result[index] = value[first + index];
24090
+ }
24091
+ return budgetProducedValue(result, options.budget);
24092
+ }
24035
24093
  case "concat":
24036
24094
  return budgetProducedValue(
24037
24095
  Reflect.apply(Array.prototype.concat, value, [...args]),
@@ -24058,7 +24116,7 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24058
24116
  );
24059
24117
  case "sort":
24060
24118
  if (args[0] === void 0) {
24061
- value.sort();
24119
+ Reflect.apply(Array.prototype.sort, value, []);
24062
24120
  budgetProducedValue(value, options.budget);
24063
24121
  return value;
24064
24122
  }
@@ -24066,11 +24124,17 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24066
24124
  budgetProducedValue(value, options.budget);
24067
24125
  return value;
24068
24126
  case "reverse":
24069
- value.reverse();
24127
+ Reflect.apply(Array.prototype.reverse, value, []);
24070
24128
  budgetProducedValue(value, options.budget);
24071
24129
  return value;
24072
24130
  case "toSorted": {
24073
- const result = Array.from(value);
24131
+ const length = value.length;
24132
+ options.budget.allocateArrayLength(length);
24133
+ const result = new Array(length);
24134
+ for (let index = 0; index < length; index += 1) {
24135
+ options.budget.visitNode();
24136
+ result[index] = value[index];
24137
+ }
24074
24138
  if (args[0] === void 0) {
24075
24139
  result.sort();
24076
24140
  } else {
@@ -24079,13 +24143,29 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24079
24143
  return budgetProducedValue(result, options.budget);
24080
24144
  }
24081
24145
  case "toReversed": {
24082
- const result = Array.from(value);
24083
- result.reverse();
24146
+ const length = value.length;
24147
+ options.budget.allocateArrayLength(length);
24148
+ const result = new Array(length);
24149
+ for (let index = 0; index < length; index += 1) {
24150
+ options.budget.visitNode();
24151
+ result[index] = value[length - index - 1];
24152
+ }
24084
24153
  return budgetProducedValue(result, options.budget);
24085
24154
  }
24086
24155
  case "toSpliced": {
24087
- const result = Array.from(value);
24088
- Reflect.apply(Array.prototype.splice, result, [...args]);
24156
+ const length = value.length;
24157
+ const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
24158
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
24159
+ const inserted = Math.max(args.length - 2, 0);
24160
+ const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(Math.max(toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context)), 0), length - first);
24161
+ const resultLength = length + inserted - deleted;
24162
+ if (resultLength > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24163
+ options.budget.allocateArrayLength(resultLength);
24164
+ const result = new Array(resultLength);
24165
+ for (let index = 0; index < resultLength; index += 1) {
24166
+ options.budget.visitNode();
24167
+ result[index] = index < first ? value[index] : index < first + inserted ? args[index - first + 2] : value[index - inserted + deleted];
24168
+ }
24089
24169
  return budgetProducedValue(result, options.budget);
24090
24170
  }
24091
24171
  case "with": {
@@ -24099,39 +24179,42 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24099
24179
  const result = [];
24100
24180
  for (let position = 0; position < length; position += 1) {
24101
24181
  options.budget.visitNode();
24102
- result[position] = position === actualIndex ? args[1] : Object.hasOwn(value, position) ? value[position] : void 0;
24182
+ result[position] = position === actualIndex ? args[1] : Array.isArray(value) && !Object.hasOwn(value, position) ? void 0 : value[position];
24103
24183
  }
24104
24184
  return budgetProducedValue(result, options.budget);
24105
24185
  }
24106
24186
  case "push": {
24107
- appendArrayValues(value, args);
24108
- const nextLength = value.length;
24187
+ const nextLength = appendArrayValues(value, args);
24109
24188
  budgetProducedValue(value, options.budget);
24110
24189
  return nextLength;
24111
24190
  }
24112
24191
  case "pop":
24113
- return budgetProducedValue(value.pop(), options.budget);
24192
+ return budgetProducedValue(Reflect.apply(Array.prototype.pop, value, []), options.budget);
24114
24193
  case "shift":
24115
- return budgetProducedValue(value.shift(), options.budget);
24194
+ return budgetProducedValue(Reflect.apply(Array.prototype.shift, value, []), options.budget);
24116
24195
  case "unshift": {
24117
- prependArrayValues(value, args);
24118
- const nextLength = value.length;
24196
+ const nextLength = prependArrayValues(value, args);
24119
24197
  budgetProducedValue(value, options.budget);
24120
24198
  return nextLength;
24121
24199
  }
24122
24200
  }
24123
24201
  }
24124
24202
  function appendArrayValues(target, values) {
24203
+ let length = target.length;
24204
+ if (length + values.length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24125
24205
  for (const value of values) {
24126
- target.push(value);
24206
+ target[length++] = value;
24127
24207
  }
24208
+ target.length = length;
24209
+ return length;
24128
24210
  }
24129
24211
  function prependArrayValues(target, values) {
24130
24212
  const originalLength = target.length;
24131
- target.length = originalLength + values.length;
24132
- for (let index = originalLength - 1; index >= 0; index -= 1) {
24213
+ const length = originalLength + values.length;
24214
+ if (length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24215
+ for (let index = values.length === 0 ? -1 : originalLength - 1; index >= 0; index -= 1) {
24133
24216
  const targetIndex = index + values.length;
24134
- if (Object.hasOwn(target, index)) {
24217
+ if (index in target) {
24135
24218
  target[targetIndex] = target[index];
24136
24219
  } else {
24137
24220
  delete target[targetIndex];
@@ -24140,6 +24223,8 @@ function prependArrayValues(target, values) {
24140
24223
  for (let index = 0; index < values.length; index += 1) {
24141
24224
  target[index] = values[index];
24142
24225
  }
24226
+ target.length = length;
24227
+ return length;
24143
24228
  }
24144
24229
  function isCallbackArrayMethod(methodName) {
24145
24230
  return methodName === "map" || methodName === "filter" || methodName === "find" || methodName === "findIndex" || methodName === "findLast" || methodName === "findLastIndex" || methodName === "some" || methodName === "every" || methodName === "reduce" || methodName === "reduceRight" || methodName === "forEach" || methodName === "flatMap" || methodName === "sort";
@@ -24155,6 +24240,7 @@ function getRequiredCallback(methodName, value) {
24155
24240
  }
24156
24241
  async function mapArray(value, callback, options, stack, thisValue) {
24157
24242
  const length = value.length;
24243
+ options.budget.allocateArrayLength(length);
24158
24244
  const result = new Array(length);
24159
24245
  options.budget.setRetainedValues(result, () => [result]);
24160
24246
  try {
@@ -24300,7 +24386,7 @@ async function reduceFromLeft(value, callback, accumulator, startIndex, length,
24300
24386
  if (!(index in value)) {
24301
24387
  continue;
24302
24388
  }
24303
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
24389
+ current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
24304
24390
  }
24305
24391
  return current;
24306
24392
  } finally {
@@ -24317,7 +24403,7 @@ async function reduceFromRight(value, callback, accumulator, startIndex, length,
24317
24403
  if (!(index in value)) {
24318
24404
  continue;
24319
24405
  }
24320
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
24406
+ current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
24321
24407
  }
24322
24408
  return current;
24323
24409
  } finally {
@@ -24440,7 +24526,7 @@ async function compareEntries(left, right, comparator, options, stack) {
24440
24526
  return Number.isNaN(result) ? 0 : result;
24441
24527
  }
24442
24528
  async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
24443
- return options.callClosure(callback, [value, index, array], stack, thisValue);
24529
+ return options.callClosure(callback, [value, index, arrayLikeSources.get(array) ?? array], stack, thisValue);
24444
24530
  }
24445
24531
  function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24446
24532
  for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
@@ -24452,6 +24538,7 @@ function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24452
24538
  return -1;
24453
24539
  }
24454
24540
  function budgetProducedValue(value, budget) {
24541
+ if (typeof value === "object" && value !== null) value = arrayLikeSources.get(value) ?? value;
24455
24542
  allocateProducedValue(value, budget, /* @__PURE__ */ new WeakSet());
24456
24543
  return value;
24457
24544
  }
@@ -28632,6 +28719,10 @@ async function evaluateNumberMethodCall(node, target, methodName, context) {
28632
28719
  function createArrayMethodOptions(context) {
28633
28720
  return {
28634
28721
  budget: context.budget,
28722
+ context: createCoercionContext(context),
28723
+ hasProperty: (value, property) => hasSandboxProperty(value, property, context),
28724
+ setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
28725
+ deleteProperty: deleteSandboxProperty,
28635
28726
  callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, void 0, thisValue)
28636
28727
  };
28637
28728
  }
@@ -33213,4 +33304,4 @@ export {
33213
33304
  FileSnapshotBackend,
33214
33305
  run
33215
33306
  };
33216
- //# sourceMappingURL=chunk-DVWTNFTV.js.map
33307
+ //# sourceMappingURL=chunk-G2KH7I4M.js.map