poe-code 14.0.64 → 14.0.66

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.
Files changed (73) hide show
  1. package/dist/index.js +8832 -7273
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-js/dist/chunks/{chunk-3EXDJDQM.js → chunk-MKTUVVEB.js} +2 -2
  6. package/packages/safe-js/dist/chunks/{chunk-XO7B4P27.js → chunk-YKISHTWT.js} +4474 -2978
  7. package/packages/safe-js/dist/chunks/chunk-YKISHTWT.js.map +7 -0
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.js +1 -1
  10. package/packages/safe-js/dist/index.js +2 -2
  11. package/packages/safe-js/dist/index.js.map +1 -1
  12. package/packages/safe-js/dist/interp/accessors.d.ts +9 -0
  13. package/packages/safe-js/dist/interp/accessors.js +68 -0
  14. package/packages/safe-js/dist/interp/async.d.ts +13 -2
  15. package/packages/safe-js/dist/interp/async.js +19 -9
  16. package/packages/safe-js/dist/interp/classes.d.ts +4 -0
  17. package/packages/safe-js/dist/interp/classes.js +182 -0
  18. package/packages/safe-js/dist/interp/exceptions.d.ts +1 -1
  19. package/packages/safe-js/dist/interp/exceptions.js +51 -9
  20. package/packages/safe-js/dist/interp/globals/collections.js +53 -16
  21. package/packages/safe-js/dist/interp/globals/console-json.js +41 -26
  22. package/packages/safe-js/dist/interp/globals/object-array.d.ts +2 -1
  23. package/packages/safe-js/dist/interp/globals/object-array.js +230 -69
  24. package/packages/safe-js/dist/interp/globals/object.js +13 -2
  25. package/packages/safe-js/dist/interp/globals/primitives.js +16 -5
  26. package/packages/safe-js/dist/interp/interpreter.d.ts +2 -2
  27. package/packages/safe-js/dist/interp/interpreter.js +168 -61
  28. package/packages/safe-js/dist/interp/iteration.js +13 -0
  29. package/packages/safe-js/dist/interp/methods/array.d.ts +1 -1
  30. package/packages/safe-js/dist/interp/methods/array.js +368 -109
  31. package/packages/safe-js/dist/interp/methods/function.d.ts +1 -1
  32. package/packages/safe-js/dist/interp/methods/function.js +56 -20
  33. package/packages/safe-js/dist/interp/methods/regex.js +1 -1
  34. package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
  35. package/packages/safe-js/dist/interp/object-model.js +48 -10
  36. package/packages/safe-js/dist/interp/patterns.d.ts +3 -3
  37. package/packages/safe-js/dist/interp/patterns.js +36 -17
  38. package/packages/safe-js/dist/interp/promise.d.ts +1 -1
  39. package/packages/safe-js/dist/interp/promise.js +103 -63
  40. package/packages/safe-js/dist/interp/string-coercion.d.ts +1 -0
  41. package/packages/safe-js/dist/interp/string-coercion.js +47 -37
  42. package/packages/safe-js/dist/interp/values.d.ts +4 -2
  43. package/packages/safe-js/dist/interp/values.js +26 -1
  44. package/packages/safe-js/dist/lint/class-elements.d.ts +5 -0
  45. package/packages/safe-js/dist/lint/class-elements.js +20 -0
  46. package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +16 -0
  47. package/packages/safe-js/dist/lint/rules/AS-destructure-null-default.js +9 -0
  48. package/packages/safe-js/dist/lint/rules/AS-export-import-meta.js +9 -0
  49. package/packages/safe-js/dist/lint/rules/AS-floating-promise.js +9 -0
  50. package/packages/safe-js/dist/lint/rules/AS-frontmatter-field-unused.js +9 -0
  51. package/packages/safe-js/dist/lint/rules/AS-jsdoc-type.js +9 -0
  52. package/packages/safe-js/dist/lint/rules/AS-large-literal.js +9 -0
  53. package/packages/safe-js/dist/lint/rules/AS-missing-async.js +16 -0
  54. package/packages/safe-js/dist/lint/rules/AS-mutating-frozen.js +9 -0
  55. package/packages/safe-js/dist/lint/rules/AS-needless-template.js +9 -0
  56. package/packages/safe-js/dist/lint/rules/AS-shadow-global.js +12 -0
  57. package/packages/safe-js/dist/lint/rules/AS-unbounded-loop.js +11 -0
  58. package/packages/safe-js/dist/lint/rules/AS-unreachable.js +9 -0
  59. package/packages/safe-js/dist/lint/rules/AS-unused-import.js +16 -2
  60. package/packages/safe-js/dist/lint/rules/AS001.js +0 -1
  61. package/packages/safe-js/dist/lint/rules/AS003.js +16 -2
  62. package/packages/safe-js/dist/lint/rules/AS006-007.js +16 -2
  63. package/packages/safe-js/dist/lint/rules/AS009.js +20 -1
  64. package/packages/safe-js/dist/lint/rules/AS010.js +9 -0
  65. package/packages/safe-js/dist/lint/rules/AS011.js +9 -0
  66. package/packages/safe-js/dist/lint/rules/AS015.js +9 -0
  67. package/packages/safe-js/dist/parse/function-source.d.ts +2 -2
  68. package/packages/safe-js/dist/parse/parser.d.ts +42 -2
  69. package/packages/safe-js/dist/parse/parser.js +208 -35
  70. package/packages/safe-js/dist/parse/tokenizer.js +3 -0
  71. package/packages/safe-js/dist/parse.d.ts +1 -1
  72. package/packages/safe-js/dist/chunks/chunk-XO7B4P27.js.map +0 -7
  73. /package/packages/safe-js/dist/chunks/{chunk-3EXDJDQM.js.map → chunk-MKTUVVEB.js.map} +0 -0
@@ -1,10 +1,12 @@
1
1
  import { promiseReplayContext } from "./promise-replay.js";
2
+ import { readPropertyDescriptor, writePropertyDescriptor } from "./accessors.js";
2
3
  import { deleteHostObjectMember, getHostObjectKeys, getHostObjectMember, hasHostObjectMember, isGuestHostObject, setHostObjectMember } from "./host-capabilities.js";
3
4
  import { toPropertyKey } from "./property-key.js";
4
5
  import { assertPromiseExecutionAllowed } from "./promise-tracker.js";
5
6
  import { SandboxJobQueue, runAsyncPrefix, suspendJob } from "./jobs.js";
6
7
  import { withCancellationSignal } from "./cancel.js";
7
8
  import { retainValues } from "./resources.js";
9
+ import { evaluateClass } from "./classes.js";
8
10
  import { sandboxString } from "./string-coercion.js";
9
11
  import { attachErrorSpan, formatErrorStack, replaceErrorStack } from "../error/shape.js";
10
12
  import { evaluateArrowFunctionExpression, evaluateFunctionExpression, evaluateAwaitExpression, emitResumeBreakpoint, createInterpretedClosure, normalizeClosureResult } from "./async.js";
@@ -14,7 +16,7 @@ import { CompileScope, RegexCompileGuard } from "./regex/compile-guard.js";
14
16
  import { createCapturedException, createThrowCompletion, evaluateThrowStatement as evaluateThrowStatementResult, evaluateTryStatement as evaluateTryStatementResult, isCapturedException, isInterpreterError, surfaceThrownValue } from "./exceptions.js";
15
17
  import { callArrayMethod, getArrayMember, isArrayMethodName } from "./methods/array.js";
16
18
  import { getFunctionMember } from "./methods/function.js";
17
- import { getBoxedPrototype, getGuestFunctionProperty, getSandboxPrototype, hasExplicitSandboxPrototype, isDefaultBoxedMethod, isGuestClosure, materializeFunctionProperties, setSandboxPrototype } from "./object-model.js";
19
+ import { getBoxedPrototype, getSandboxPropertyDescriptor, getSandboxPrototype, hasExplicitSandboxPrototype, isDefaultBoxedMethod, isGuestClosure, materializeFunctionProperties, setSandboxPrototype } from "./object-model.js";
18
20
  import { getStringIndex } from "./methods/string.js";
19
21
  import { assertSandboxDataDepth } from "../graph-depth.js";
20
22
  import { callMapMethod, getMapMember, isMapMethodName } from "./methods/map.js";
@@ -50,6 +52,15 @@ const dispatchTable = {
50
52
  BlockStatement: evaluateBlockStatement,
51
53
  BooleanLiteral: evaluatePrimitiveLiteral,
52
54
  CallExpression: evaluateCallExpression,
55
+ ClassDeclaration: (node, context) => evaluateClass(node, context, evaluateNode, createCoercionContext(context)),
56
+ ClassExpression: (node, context) => evaluateClass(node, context, evaluateNode, createCoercionContext(context)),
57
+ NewTargetExpression: async (_node, context) => ({ kind: "normal", hasValue: true, value: context.functionEnvironment?.newTarget }),
58
+ Super: async (_node, context) => {
59
+ const home = context.functionEnvironment?.homeObject;
60
+ if (home === undefined)
61
+ throw new ReferenceError("Super binding is unavailable.");
62
+ return { kind: "normal", hasValue: true, value: getSandboxPrototype(home, context.budget) };
63
+ },
53
64
  ConditionalExpression: evaluateConditionalExpression,
54
65
  ContinueStatement: evaluateContinueStatement,
55
66
  DoWhileStatement: evaluateDoWhileStatement,
@@ -182,6 +193,8 @@ export async function interpret(node, options = {}) {
182
193
  export { Scope } from "./scope.js";
183
194
  async function evaluateNode(node, context) {
184
195
  context.assertActive?.();
196
+ if (context.inferredName !== undefined && node.type !== "ClassExpression")
197
+ context = { ...context, inferredName: undefined };
185
198
  const replayWait = promiseReplayContext.getStore()?.beforeNode(node.nodeId);
186
199
  if (replayWait !== undefined)
187
200
  await suspendJob(replayWait);
@@ -332,7 +345,13 @@ async function evaluateObjectExpression(node, context) {
332
345
  const releaseKey = retainValues(context.budget, () => [key.value]);
333
346
  let value;
334
347
  try {
335
- value = await evaluateNode(property.value, context);
348
+ value = await evaluateNode(property.value, {
349
+ ...context,
350
+ inferredName: String(key.value),
351
+ ...(property.value.type === "FunctionExpression" && property.value.method === true
352
+ ? { functionEnvironment: { homeObject: object } }
353
+ : {})
354
+ });
336
355
  }
337
356
  finally {
338
357
  releaseKey();
@@ -359,7 +378,8 @@ async function evaluateObjectExpression(node, context) {
359
378
  }
360
379
  }
361
380
  function isObjectPrototypeSetterProperty(property, key) {
362
- return !property.computed && !property.shorthand && key === "__proto__";
381
+ return !property.computed && !property.shorthand && key === "__proto__" &&
382
+ !(property.value.type === "FunctionExpression" && property.value.method === true);
363
383
  }
364
384
  async function evaluateTemplateLiteral(node, context) {
365
385
  let value = context.budget.allocateString(node.quasis[0]?.value.cooked ?? "");
@@ -390,22 +410,33 @@ async function evaluateTemplateLiteral(node, context) {
390
410
  }
391
411
  }
392
412
  async function evaluateTaggedTemplateExpression(node, context) {
393
- const tag = await evaluateNode(node.tag, context);
394
- if (tag.kind !== "normal") {
395
- return tag;
396
- }
397
- if (!isSandboxClosure(tag.value)) {
398
- throw new TypeError("Tagged template tag must be a function.");
399
- }
400
- const values = await evaluateTemplateExpressionValues(node.quasi, context);
401
- if (!values.ok) {
402
- return values.result;
403
- }
404
- return {
405
- kind: "normal",
406
- hasValue: true,
407
- value: await invokeSandboxClosure(tag.value, [createTaggedTemplateStrings(node.quasi, context), ...values.value], context, [...context.callStack, formatStackFrame(node, tag.value.name)])
413
+ const invokeTag = async (tag, receiver) => {
414
+ if (!isSandboxClosure(tag))
415
+ throw new TypeError("Tagged template tag must be a function.");
416
+ const release = retainValues(context.budget, () => [tag, receiver]);
417
+ try {
418
+ const values = await evaluateTemplateExpressionValues(node.quasi, context);
419
+ if (!values.ok)
420
+ return values.result;
421
+ return {
422
+ kind: "normal", hasValue: true,
423
+ value: await invokeSandboxClosure(tag, [createTaggedTemplateStrings(node.quasi, context), ...values.value], context, [...context.callStack, formatStackFrame(node, tag.name)], node.span, receiver)
424
+ };
425
+ }
426
+ finally {
427
+ release();
428
+ }
408
429
  };
430
+ if (node.tag.type === "MemberExpression")
431
+ return evaluateMemberAccess(node.tag, context, async (member) => {
432
+ if (member.kind === "nullish")
433
+ throw new TypeError("Tagged template tag must be a function.");
434
+ const key = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
435
+ const receiver = member.superReceiver === undefined ? member.object : member.superReceiver.value;
436
+ return invokeTag(await getPropertyValue(member.object, key, context, receiver), receiver);
437
+ });
438
+ const tag = await evaluateNode(node.tag, context);
439
+ return tag.kind === "normal" ? invokeTag(tag.value, undefined) : tag;
409
440
  }
410
441
  async function evaluateTemplateExpressionValues(node, context) {
411
442
  const values = [];
@@ -490,7 +521,8 @@ async function evaluateBinaryExpression(node, context) {
490
521
  if (isSandboxBox(rightValue) && (!equality || (left.value !== null && left.value !== undefined && typeof left.value !== "object")))
491
522
  rightValue = await toNumericPrimitive(rightValue, context);
492
523
  }
493
- const value = applyBinaryOperator(node, leftValue, rightValue, context);
524
+ const operation = applyBinaryOperator(node, leftValue, rightValue, context);
525
+ const value = operation instanceof Promise ? await operation : operation;
494
526
  return {
495
527
  kind: "normal",
496
528
  hasValue: true,
@@ -552,7 +584,7 @@ async function evaluateAssignmentExpression(node, context) {
552
584
  value: current
553
585
  };
554
586
  }
555
- const right = await evaluateNode(node.right, context);
587
+ const right = await evaluateNode(node.right, { ...context, inferredName: node.left.type === "Identifier" ? node.left.name : undefined });
556
588
  if (right.kind !== "normal") {
557
589
  return right;
558
590
  }
@@ -584,7 +616,7 @@ async function evaluateMemberAssignmentExpression(node, context) {
584
616
  throw new TypeError("Cannot assign properties of null or undefined.");
585
617
  }
586
618
  property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
587
- current = getPropertyValue(member.object, property, context);
619
+ current = await getPropertyValue(member.object, property, context, member.superReceiver === undefined ? member.object : member.superReceiver.value);
588
620
  }
589
621
  if (node.operator === "&&=" && !isTruthy(current)) {
590
622
  return {
@@ -626,7 +658,10 @@ async function evaluateMemberAssignmentExpression(node, context) {
626
658
  }
627
659
  operands = [value];
628
660
  property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
629
- setSandboxProperty(member.object, property, value, context.budget);
661
+ if (member.superReceiver === undefined)
662
+ await setSandboxProperty(member.object, property, value, context.budget, true, createCoercionContext(context));
663
+ else
664
+ await setSuperProperty(member.object, member.superReceiver.value, property, value, context);
630
665
  return {
631
666
  kind: "normal",
632
667
  hasValue: true,
@@ -772,7 +807,7 @@ async function evaluateVariableDeclaration(node, context) {
772
807
  hasValue: true,
773
808
  value: undefined
774
809
  }
775
- : await evaluateNode(declarator.init, context);
810
+ : await evaluateNode(declarator.init, { ...context, inferredName: declarator.id.type === "Identifier" ? declarator.id.name : undefined });
776
811
  if (value.kind !== "normal") {
777
812
  return value;
778
813
  }
@@ -946,6 +981,11 @@ function predeclareStatementListBindings(statements, context, functionBody = fal
946
981
  const { scope } = context;
947
982
  const names = new Set();
948
983
  for (const statement of statements) {
984
+ if (statement.type === "ClassDeclaration") {
985
+ scope.predeclare(statement.id.name, "let");
986
+ names.add(statement.id.name);
987
+ continue;
988
+ }
949
989
  if (statement.type === "FunctionDeclaration") {
950
990
  const name = statement.id.name;
951
991
  if (names.has(name) && !(functionBody && scope.getOwnBindingKind(name) === "var")) {
@@ -1646,6 +1686,8 @@ async function evaluateDeleteExpression(node, context) {
1646
1686
  throw createError("UNSUPPORTED_NODE", node, "Unary operator 'delete' requires a member target.");
1647
1687
  }
1648
1688
  return evaluateMemberAccess(node.argument, context, async (member) => {
1689
+ if (member.kind === "resolved" && member.superReceiver !== undefined)
1690
+ throw new ReferenceError("Cannot delete a super property.");
1649
1691
  if (member.kind === "nullish" || member.object === null || member.object === undefined) {
1650
1692
  if (member.kind === "nullish") {
1651
1693
  return {
@@ -1703,9 +1745,12 @@ async function evaluateMemberUpdateExpression(node, context) {
1703
1745
  throw new TypeError("Cannot update properties of null or undefined.");
1704
1746
  }
1705
1747
  const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
1706
- const current = toNumber(await toNumericPrimitive(getPropertyValue(member.object, property, context), context));
1748
+ const current = toNumber(await toNumericPrimitive(await getPropertyValue(member.object, property, context, member.superReceiver === undefined ? member.object : member.superReceiver.value), context));
1707
1749
  const next = node.operator === "++" ? current + 1 : current - 1;
1708
- setSandboxProperty(member.object, property, next, context.budget);
1750
+ if (member.superReceiver === undefined)
1751
+ await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
1752
+ else
1753
+ await setSuperProperty(member.object, member.superReceiver.value, property, next, context);
1709
1754
  return {
1710
1755
  kind: "normal",
1711
1756
  hasValue: true,
@@ -1723,19 +1768,23 @@ async function evaluateMemberExpression(node, context) {
1723
1768
  return {
1724
1769
  kind: "normal",
1725
1770
  hasValue: true,
1726
- value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
1771
+ value: await getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context, member.superReceiver === undefined ? member.object : member.superReceiver.value)
1727
1772
  };
1728
1773
  });
1729
1774
  }
1730
- function getPropertyValue(target, property, context) {
1775
+ function getPropertyValue(target, property, context, receiver = target) {
1731
1776
  if (isGuestHostObject(target))
1732
1777
  return getHostObjectMember(target, String(property));
1778
+ const descriptor = getSandboxPropertyDescriptor(target, property, context.budget);
1779
+ if (descriptor !== undefined)
1780
+ return readPropertyDescriptor(descriptor, receiver, createCoercionContext(context), true);
1733
1781
  if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
1734
1782
  const prototype = getBoxedPrototype(target, context.budget);
1735
1783
  if (prototype !== undefined) {
1736
- if (typeof target === "string" && (property === "length" || getStringIndex(property) !== undefined))
1784
+ if (typeof target === "string" &&
1785
+ (property === "length" || getStringIndex(property) !== undefined))
1737
1786
  return getStringMember(target, property, context.budget);
1738
- return getMemberValue(prototype, property, context);
1787
+ return getPropertyValue(prototype, property, context, receiver);
1739
1788
  }
1740
1789
  }
1741
1790
  if (typeof target === "string")
@@ -1771,13 +1820,22 @@ export function createPatternContext(context, scope = context.scope, evaluate =
1771
1820
  const evaluationContext = { ...context, scope };
1772
1821
  return {
1773
1822
  budget: context.budget,
1774
- evaluate: node => evaluate(node, evaluationContext),
1775
- toPropertyKey: value => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
1823
+ evaluate: (node, inferredName) => evaluate(node, { ...evaluationContext, inferredName }),
1824
+ toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
1776
1825
  getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
1777
- setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget)
1826
+ setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget, true, createCoercionContext(evaluationContext))
1778
1827
  };
1779
1828
  }
1780
1829
  async function evaluateCallExpression(node, context) {
1830
+ if (node.callee.type === "Super") {
1831
+ const construction = context.functionEnvironment?.construction;
1832
+ if (construction === undefined)
1833
+ throw new ReferenceError("Super constructor binding is unavailable.");
1834
+ const args = await evaluateCallArguments(node.arguments, context);
1835
+ if (!args.ok)
1836
+ return args.result;
1837
+ return { kind: "normal", hasValue: true, value: await construction.superCall(args.value) };
1838
+ }
1781
1839
  if (node.callee.type === "MemberExpression") {
1782
1840
  context.budget.visitNode();
1783
1841
  context.stats.nodeVisits += 1;
@@ -1847,6 +1905,7 @@ function attachFatalSandboxErrorContext(error, node, stackFrames) {
1847
1905
  replaceErrorStack(error, stackFrames);
1848
1906
  }
1849
1907
  async function evaluateMemberAccess(node, context, consume) {
1908
+ const superReceiver = node.object.type === "Super" ? { value: context.scope.lookup("this") } : undefined;
1850
1909
  const object = await evaluateNode(node.object, context);
1851
1910
  if (object.kind !== "normal")
1852
1911
  return object;
@@ -1862,7 +1921,8 @@ async function evaluateMemberAccess(node, context, consume) {
1862
1921
  if (result.kind !== "normal")
1863
1922
  return result;
1864
1923
  property = result.value;
1865
- return await consume({ kind: "resolved", object: object.value, property });
1924
+ return await consume({ kind: "resolved", object: object.value, property,
1925
+ ...(superReceiver === undefined ? {} : { superReceiver: { value: superReceiver.value.found ? superReceiver.value.value : undefined } }) });
1866
1926
  }
1867
1927
  finally {
1868
1928
  release();
@@ -1918,6 +1978,8 @@ async function evaluateMemberCallExpression(node, context) {
1918
1978
  ...reference,
1919
1979
  property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
1920
1980
  };
1981
+ if (member.superReceiver !== undefined)
1982
+ return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context, member.superReceiver.value), context, member.superReceiver.value);
1921
1983
  if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") &&
1922
1984
  getBoxedPrototype(member.object, context.budget) !== undefined) {
1923
1985
  if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
@@ -1926,7 +1988,7 @@ async function evaluateMemberCallExpression(node, context) {
1926
1988
  if (typeof member.object === "number" && isNumberMethodName(member.property))
1927
1989
  return evaluateNumberMethodCall(node, member.object, member.property, context);
1928
1990
  }
1929
- return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
1991
+ return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
1930
1992
  }
1931
1993
  if (typeof member.object === "string" && isStringMethodName(member.property)) {
1932
1994
  return evaluateStringMethodCall(node, member.object, member.property, context);
@@ -1974,7 +2036,7 @@ async function evaluateMemberCallExpression(node, context) {
1974
2036
  return evaluateResolvedCallExpression(node, memberValue, context, member.object);
1975
2037
  }
1976
2038
  if (isSandboxClosure(member.object)) {
1977
- const memberValue = getClosureMemberValue(member.object, member.property, context);
2039
+ const memberValue = await getPropertyValue(member.object, member.property, context);
1978
2040
  if (memberValue === undefined) {
1979
2041
  throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
1980
2042
  }
@@ -1989,7 +2051,7 @@ async function evaluateMemberCallExpression(node, context) {
1989
2051
  if (!isIndexableSandboxValue(member.object)) {
1990
2052
  throw new TypeError("Attempted to read a property from a non-object value.");
1991
2053
  }
1992
- return evaluateResolvedCallExpression(node, getMemberValue(member.object, member.property, context), context, member.object);
2054
+ return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
1993
2055
  });
1994
2056
  }
1995
2057
  function evaluatePrimitiveMemberCall(node, receiverType, property, value, context) {
@@ -2174,7 +2236,8 @@ function applyBinaryOperator(node, left, right, context) {
2174
2236
  if (isFloat32ArrayConstructor(right))
2175
2237
  return isFloat32Array(left);
2176
2238
  if (isDateConstructor(right))
2177
- return isSandboxDate(left) && getDatePrototype(left, context.budget, context.compilation?.owner) !== null;
2239
+ return (isSandboxDate(left) &&
2240
+ getDatePrototype(left, context.budget, context.compilation?.owner) !== null);
2178
2241
  if (isSandboxSetConstructor(right) && isSandboxSet(left)) {
2179
2242
  return true;
2180
2243
  }
@@ -2184,17 +2247,21 @@ function applyBinaryOperator(node, left, right, context) {
2184
2247
  if (isGuestClosure(right)) {
2185
2248
  if (typeof left !== "object" || left === null)
2186
2249
  return false;
2187
- const prototype = getGuestFunctionProperty(right, "prototype");
2188
- if (typeof prototype !== "object" || prototype === null) {
2189
- throw new TypeError("Function has a non-object prototype in instanceof check.");
2190
- }
2191
- let depth = 0;
2192
- for (let current = getSandboxPrototype(left, context.budget); current !== null; current = getSandboxPrototype(current, context.budget)) {
2193
- context.budget.visitNode();
2194
- assertSandboxDataDepth(depth++);
2195
- if (current === prototype)
2196
- return true;
2197
- }
2250
+ const check = (prototype) => {
2251
+ if (typeof prototype !== "object" || prototype === null) {
2252
+ throw new TypeError("Function has a non-object prototype in instanceof check.");
2253
+ }
2254
+ let depth = 0;
2255
+ for (let current = getSandboxPrototype(left, context.budget); current !== null; current = getSandboxPrototype(current, context.budget)) {
2256
+ context.budget.visitNode();
2257
+ assertSandboxDataDepth(depth++);
2258
+ if (current === prototype)
2259
+ return true;
2260
+ }
2261
+ return false;
2262
+ };
2263
+ const prototype = getPropertyValue(right, "prototype", context);
2264
+ return prototype instanceof Promise ? prototype.then(check) : check(prototype);
2198
2265
  }
2199
2266
  return false;
2200
2267
  case "in":
@@ -2372,7 +2439,7 @@ async function toNumericPrimitive(value, context) {
2372
2439
  }
2373
2440
  if (isIndexableSandboxValue(value)) {
2374
2441
  for (const methodName of ["valueOf", "toString"]) {
2375
- const method = getMemberValue(value, methodName, context);
2442
+ const method = await getPropertyValue(value, methodName, context);
2376
2443
  if (methodName === "toString" && method === undefined && !Object.hasOwn(value, methodName)) {
2377
2444
  return toString(value);
2378
2445
  }
@@ -2468,7 +2535,7 @@ function getArrayMemberValue(target, property, context) {
2468
2535
  }
2469
2536
  return getArrayMember(target, property, createArrayMethodOptions(context));
2470
2537
  }
2471
- export function setSandboxProperty(target, property, value, budget) {
2538
+ export function setSandboxProperty(target, property, value, budget, checkInherited = true, context) {
2472
2539
  if (isSandboxDate(target))
2473
2540
  throw new TypeError("Date own properties are not supported.");
2474
2541
  if (isGuestHostObject(target)) {
@@ -2476,6 +2543,11 @@ export function setSandboxProperty(target, property, value, budget) {
2476
2543
  return;
2477
2544
  }
2478
2545
  const prototypeOwner = target;
2546
+ if (checkInherited) {
2547
+ const descriptor = getSandboxPropertyDescriptor(target, property, budget);
2548
+ if (descriptor !== undefined && !("value" in descriptor))
2549
+ return writePropertyDescriptor(descriptor, target, value, context);
2550
+ }
2479
2551
  if (isGuestClosure(target))
2480
2552
  target = materializeFunctionProperties(target);
2481
2553
  if (isFloat32Array(target)) {
@@ -2505,7 +2577,7 @@ export function setSandboxProperty(target, property, value, budget) {
2505
2577
  Object.defineProperty(target, key, { value });
2506
2578
  }
2507
2579
  else {
2508
- if (typeof prototypeOwner === "object" && prototypeOwner !== null) {
2580
+ if (checkInherited && typeof prototypeOwner === "object" && prototypeOwner !== null) {
2509
2581
  let depth = 0;
2510
2582
  for (let prototype = getSandboxPrototype(prototypeOwner, budget); prototype !== null; prototype = getSandboxPrototype(prototype, budget)) {
2511
2583
  budget.visitNode();
@@ -2522,6 +2594,28 @@ export function setSandboxProperty(target, property, value, budget) {
2522
2594
  defineSandboxProperty(target, key, value);
2523
2595
  }
2524
2596
  }
2597
+ function setSuperProperty(base, receiver, key, value, context) {
2598
+ const budget = context.budget;
2599
+ if (typeof base !== "object" || base === null)
2600
+ throw new TypeError("Cannot assign a property of null.");
2601
+ let depth = 0;
2602
+ for (let current = base; current !== null; current = getSandboxPrototype(current, budget)) {
2603
+ budget.visitNode();
2604
+ assertSandboxDataDepth(depth++);
2605
+ const properties = isSandboxClosure(current) ? current.properties : current;
2606
+ const descriptor = properties === undefined ? undefined : Object.getOwnPropertyDescriptor(properties, key);
2607
+ if (descriptor === undefined)
2608
+ continue;
2609
+ if (!("value" in descriptor))
2610
+ return writePropertyDescriptor(descriptor, receiver, value, createCoercionContext(context));
2611
+ if (descriptor.writable !== true)
2612
+ throw new TypeError(`Cannot assign to read only property '${key}'.`);
2613
+ break;
2614
+ }
2615
+ if (typeof receiver !== "object" || receiver === null)
2616
+ throw new TypeError("Super assignment requires an object receiver.");
2617
+ return setSandboxProperty(receiver, key, value, budget, false);
2618
+ }
2525
2619
  function deleteSandboxProperty(target, property) {
2526
2620
  if (isGuestHostObject(target))
2527
2621
  return deleteHostObjectMember(target, String(property));
@@ -2580,7 +2674,7 @@ function createArrayMethodOptions(context) {
2580
2674
  budget: context.budget,
2581
2675
  context: createCoercionContext(context),
2582
2676
  hasProperty: (value, property) => hasSandboxProperty(value, property, context),
2583
- setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
2677
+ setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget, true, createCoercionContext(context)),
2584
2678
  deleteProperty: deleteSandboxProperty,
2585
2679
  callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, undefined, thisValue)
2586
2680
  };
@@ -2600,10 +2694,10 @@ function createSetMethodOptions(context) {
2600
2694
  function createFunctionMethodOptions(context) {
2601
2695
  return {
2602
2696
  budget: context.budget,
2603
- callClosure: (closure, args, stack, thisValue, construct) => invokeSandboxClosure(closure, args, context, stack, undefined, thisValue, construct)
2697
+ callClosure: (closure, args, stack, thisValue, construct, newTarget) => invokeSandboxClosure(closure, args, context, stack, undefined, thisValue, construct, newTarget)
2604
2698
  };
2605
2699
  }
2606
- async function invokeSandboxClosure(callee, args, context, stack, span, thisValue = undefined, construct = false) {
2700
+ async function invokeSandboxClosure(callee, args, context, stack, span, thisValue = undefined, construct = false, newTarget) {
2607
2701
  const leaveCall = context.budget.enterCall();
2608
2702
  try {
2609
2703
  const invoke = construct ? callee.construct : callee.call;
@@ -2614,10 +2708,11 @@ async function invokeSandboxClosure(callee, args, context, stack, span, thisValu
2614
2708
  {
2615
2709
  stack,
2616
2710
  thisValue,
2711
+ newTarget: construct ? newTarget ?? callee : undefined,
2617
2712
  compilation: context.compilation,
2618
2713
  getProperty: (value, property) => getPropertyValue(value, property, context),
2619
2714
  reconcileData: (value) => reconcileDataBudget(context.budget, context.stats, context.scope, value, context.compilation, context.compilation?.parent),
2620
- invokeClosure: (closure, argumentsList, receiver, asConstructor) => invokeSandboxClosure(closure, argumentsList, context, stack, span, receiver, asConstructor),
2715
+ invokeClosure: (closure, argumentsList, receiver, asConstructor, target) => invokeSandboxClosure(closure, argumentsList, context, stack, span, receiver, asConstructor, target),
2621
2716
  ...(span === undefined ? {} : { span })
2622
2717
  }
2623
2718
  ]);
@@ -2728,16 +2823,28 @@ async function evaluateObjectSpread(node, context) {
2728
2823
  }
2729
2824
  return { ok: true, value: entries };
2730
2825
  }
2731
- if ((isSandboxClosure(value.value) && !isGuestClosure(value.value)) || isSandboxPromise(value.value)) {
2826
+ if ((isSandboxClosure(value.value) && !isGuestClosure(value.value)) ||
2827
+ isSandboxPromise(value.value)) {
2732
2828
  throw new TypeError(`Cannot spread ${describeObjectSpreadValue(value.value)} into object literal.`);
2733
2829
  }
2734
- const spreadValue = isGuestClosure(value.value) ? value.value.properties ?? {} : Object(value.value);
2830
+ const spreadValue = isGuestClosure(value.value)
2831
+ ? (value.value.properties ?? {})
2832
+ : Object(value.value);
2735
2833
  const keys = Object.keys(spreadValue);
2736
2834
  context.budget.allocateArrayLength(keys.length);
2737
- return {
2738
- ok: true,
2739
- value: keys.map((key) => [key, spreadValue[key]])
2740
- };
2835
+ const entries = [];
2836
+ const release = retainValues(context.budget, () => [value.value, entries]);
2837
+ try {
2838
+ for (const key of keys) {
2839
+ if (!hasOwnSandboxProperty(value.value, key, true))
2840
+ continue;
2841
+ entries.push([key, await getPropertyValue(value.value, key, context)]);
2842
+ }
2843
+ return { ok: true, value: entries };
2844
+ }
2845
+ finally {
2846
+ release();
2847
+ }
2741
2848
  }
2742
2849
  function describeObjectSpreadValue(value) {
2743
2850
  if (value === null) {
@@ -44,6 +44,19 @@ export function getSandboxIterator(value, budget, context) {
44
44
  if (isSandboxSet(value)) {
45
45
  return collectionIterator(value.values);
46
46
  }
47
+ if (Array.isArray(value) && context?.getProperty !== undefined) {
48
+ let index = 0;
49
+ return {
50
+ asynchronous: true,
51
+ snapshotIndex: () => index,
52
+ next: async () => {
53
+ if (index >= value.length)
54
+ return { done: true, value: undefined };
55
+ budget?.visitNode();
56
+ return { done: false, value: await context.getProperty(value, index++) };
57
+ }
58
+ };
59
+ }
47
60
  if ((typeof value !== "object" && typeof value !== "function") || value === null) {
48
61
  return undefined;
49
62
  }
@@ -9,7 +9,7 @@ export type ArrayMethodOptions = {
9
9
  budget: Budget;
10
10
  context?: SandboxCallContext;
11
11
  hasProperty?: (value: SandboxValue, property: string) => boolean;
12
- setProperty?: (value: SandboxValue, property: string, entry: SandboxValue) => void;
12
+ setProperty?: (value: SandboxValue, property: string, entry: SandboxValue) => void | Promise<void>;
13
13
  deleteProperty?: (value: SandboxValue, property: string | number) => boolean;
14
14
  callClosure: (closure: SandboxClosure, args: readonly SandboxValue[], stack: readonly string[], thisValue?: SandboxValue) => Promise<SandboxValue>;
15
15
  };