poe-code 14.0.65 → 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.
- package/dist/index.js +1723 -797
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-js/dist/chunks/{chunk-4VT2M7WL.js → chunk-MKTUVVEB.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-WBWD7ZCM.js → chunk-YKISHTWT.js} +1675 -772
- package/packages/safe-js/dist/chunks/chunk-YKISHTWT.js.map +7 -0
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/interp/accessors.d.ts +9 -0
- package/packages/safe-js/dist/interp/accessors.js +68 -0
- package/packages/safe-js/dist/interp/async.js +3 -3
- package/packages/safe-js/dist/interp/classes.js +10 -4
- package/packages/safe-js/dist/interp/exceptions.d.ts +1 -1
- package/packages/safe-js/dist/interp/exceptions.js +47 -8
- package/packages/safe-js/dist/interp/globals/collections.js +53 -16
- package/packages/safe-js/dist/interp/globals/console-json.js +41 -26
- package/packages/safe-js/dist/interp/globals/object-array.js +229 -68
- package/packages/safe-js/dist/interp/globals/object.js +6 -3
- package/packages/safe-js/dist/interp/globals/primitives.js +11 -5
- package/packages/safe-js/dist/interp/interpreter.d.ts +2 -2
- package/packages/safe-js/dist/interp/interpreter.js +83 -44
- package/packages/safe-js/dist/interp/iteration.js +13 -0
- package/packages/safe-js/dist/interp/methods/array.d.ts +1 -1
- package/packages/safe-js/dist/interp/methods/array.js +368 -109
- package/packages/safe-js/dist/interp/methods/function.js +56 -20
- package/packages/safe-js/dist/interp/methods/regex.js +1 -1
- package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
- package/packages/safe-js/dist/interp/object-model.js +48 -10
- package/packages/safe-js/dist/interp/patterns.d.ts +2 -2
- package/packages/safe-js/dist/interp/patterns.js +35 -16
- package/packages/safe-js/dist/interp/promise.d.ts +1 -1
- package/packages/safe-js/dist/interp/promise.js +103 -63
- package/packages/safe-js/dist/interp/string-coercion.d.ts +1 -0
- package/packages/safe-js/dist/interp/string-coercion.js +47 -37
- package/packages/safe-js/dist/interp/values.d.ts +2 -1
- package/packages/safe-js/dist/interp/values.js +26 -1
- package/packages/safe-js/dist/parse/parser.d.ts +1 -1
- package/packages/safe-js/dist/parse/parser.js +37 -8
- package/packages/safe-js/dist/chunks/chunk-WBWD7ZCM.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-4VT2M7WL.js.map → chunk-MKTUVVEB.js.map} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
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";
|
|
@@ -15,7 +16,7 @@ import { CompileScope, RegexCompileGuard } from "./regex/compile-guard.js";
|
|
|
15
16
|
import { createCapturedException, createThrowCompletion, evaluateThrowStatement as evaluateThrowStatementResult, evaluateTryStatement as evaluateTryStatementResult, isCapturedException, isInterpreterError, surfaceThrownValue } from "./exceptions.js";
|
|
16
17
|
import { callArrayMethod, getArrayMember, isArrayMethodName } from "./methods/array.js";
|
|
17
18
|
import { getFunctionMember } from "./methods/function.js";
|
|
18
|
-
import { getBoxedPrototype,
|
|
19
|
+
import { getBoxedPrototype, getSandboxPropertyDescriptor, getSandboxPrototype, hasExplicitSandboxPrototype, isDefaultBoxedMethod, isGuestClosure, materializeFunctionProperties, setSandboxPrototype } from "./object-model.js";
|
|
19
20
|
import { getStringIndex } from "./methods/string.js";
|
|
20
21
|
import { assertSandboxDataDepth } from "../graph-depth.js";
|
|
21
22
|
import { callMapMethod, getMapMember, isMapMethodName } from "./methods/map.js";
|
|
@@ -344,7 +345,13 @@ async function evaluateObjectExpression(node, context) {
|
|
|
344
345
|
const releaseKey = retainValues(context.budget, () => [key.value]);
|
|
345
346
|
let value;
|
|
346
347
|
try {
|
|
347
|
-
value = await evaluateNode(property.value, {
|
|
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
|
+
});
|
|
348
355
|
}
|
|
349
356
|
finally {
|
|
350
357
|
releaseKey();
|
|
@@ -371,7 +378,8 @@ async function evaluateObjectExpression(node, context) {
|
|
|
371
378
|
}
|
|
372
379
|
}
|
|
373
380
|
function isObjectPrototypeSetterProperty(property, key) {
|
|
374
|
-
return !property.computed && !property.shorthand && key === "__proto__"
|
|
381
|
+
return !property.computed && !property.shorthand && key === "__proto__" &&
|
|
382
|
+
!(property.value.type === "FunctionExpression" && property.value.method === true);
|
|
375
383
|
}
|
|
376
384
|
async function evaluateTemplateLiteral(node, context) {
|
|
377
385
|
let value = context.budget.allocateString(node.quasis[0]?.value.cooked ?? "");
|
|
@@ -424,7 +432,8 @@ async function evaluateTaggedTemplateExpression(node, context) {
|
|
|
424
432
|
if (member.kind === "nullish")
|
|
425
433
|
throw new TypeError("Tagged template tag must be a function.");
|
|
426
434
|
const key = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
427
|
-
|
|
435
|
+
const receiver = member.superReceiver === undefined ? member.object : member.superReceiver.value;
|
|
436
|
+
return invokeTag(await getPropertyValue(member.object, key, context, receiver), receiver);
|
|
428
437
|
});
|
|
429
438
|
const tag = await evaluateNode(node.tag, context);
|
|
430
439
|
return tag.kind === "normal" ? invokeTag(tag.value, undefined) : tag;
|
|
@@ -512,7 +521,8 @@ async function evaluateBinaryExpression(node, context) {
|
|
|
512
521
|
if (isSandboxBox(rightValue) && (!equality || (left.value !== null && left.value !== undefined && typeof left.value !== "object")))
|
|
513
522
|
rightValue = await toNumericPrimitive(rightValue, context);
|
|
514
523
|
}
|
|
515
|
-
const
|
|
524
|
+
const operation = applyBinaryOperator(node, leftValue, rightValue, context);
|
|
525
|
+
const value = operation instanceof Promise ? await operation : operation;
|
|
516
526
|
return {
|
|
517
527
|
kind: "normal",
|
|
518
528
|
hasValue: true,
|
|
@@ -606,7 +616,7 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
606
616
|
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
607
617
|
}
|
|
608
618
|
property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
609
|
-
current = getPropertyValue(member.object, property, context);
|
|
619
|
+
current = await getPropertyValue(member.object, property, context, member.superReceiver === undefined ? member.object : member.superReceiver.value);
|
|
610
620
|
}
|
|
611
621
|
if (node.operator === "&&=" && !isTruthy(current)) {
|
|
612
622
|
return {
|
|
@@ -649,9 +659,9 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
649
659
|
operands = [value];
|
|
650
660
|
property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
651
661
|
if (member.superReceiver === undefined)
|
|
652
|
-
setSandboxProperty(member.object, property, value, context.budget);
|
|
662
|
+
await setSandboxProperty(member.object, property, value, context.budget, true, createCoercionContext(context));
|
|
653
663
|
else
|
|
654
|
-
setSuperProperty(member.object, member.superReceiver.value, property, value, context
|
|
664
|
+
await setSuperProperty(member.object, member.superReceiver.value, property, value, context);
|
|
655
665
|
return {
|
|
656
666
|
kind: "normal",
|
|
657
667
|
hasValue: true,
|
|
@@ -1735,12 +1745,12 @@ async function evaluateMemberUpdateExpression(node, context) {
|
|
|
1735
1745
|
throw new TypeError("Cannot update properties of null or undefined.");
|
|
1736
1746
|
}
|
|
1737
1747
|
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
1738
|
-
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));
|
|
1739
1749
|
const next = node.operator === "++" ? current + 1 : current - 1;
|
|
1740
1750
|
if (member.superReceiver === undefined)
|
|
1741
|
-
setSandboxProperty(member.object, property, next, context.budget);
|
|
1751
|
+
await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
|
|
1742
1752
|
else
|
|
1743
|
-
setSuperProperty(member.object, member.superReceiver.value, property, next, context
|
|
1753
|
+
await setSuperProperty(member.object, member.superReceiver.value, property, next, context);
|
|
1744
1754
|
return {
|
|
1745
1755
|
kind: "normal",
|
|
1746
1756
|
hasValue: true,
|
|
@@ -1758,19 +1768,23 @@ async function evaluateMemberExpression(node, context) {
|
|
|
1758
1768
|
return {
|
|
1759
1769
|
kind: "normal",
|
|
1760
1770
|
hasValue: true,
|
|
1761
|
-
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)
|
|
1762
1772
|
};
|
|
1763
1773
|
});
|
|
1764
1774
|
}
|
|
1765
|
-
function getPropertyValue(target, property, context) {
|
|
1775
|
+
function getPropertyValue(target, property, context, receiver = target) {
|
|
1766
1776
|
if (isGuestHostObject(target))
|
|
1767
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);
|
|
1768
1781
|
if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
|
|
1769
1782
|
const prototype = getBoxedPrototype(target, context.budget);
|
|
1770
1783
|
if (prototype !== undefined) {
|
|
1771
|
-
if (typeof target === "string" &&
|
|
1784
|
+
if (typeof target === "string" &&
|
|
1785
|
+
(property === "length" || getStringIndex(property) !== undefined))
|
|
1772
1786
|
return getStringMember(target, property, context.budget);
|
|
1773
|
-
return
|
|
1787
|
+
return getPropertyValue(prototype, property, context, receiver);
|
|
1774
1788
|
}
|
|
1775
1789
|
}
|
|
1776
1790
|
if (typeof target === "string")
|
|
@@ -1807,9 +1821,9 @@ export function createPatternContext(context, scope = context.scope, evaluate =
|
|
|
1807
1821
|
return {
|
|
1808
1822
|
budget: context.budget,
|
|
1809
1823
|
evaluate: (node, inferredName) => evaluate(node, { ...evaluationContext, inferredName }),
|
|
1810
|
-
toPropertyKey: value => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
|
|
1824
|
+
toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
|
|
1811
1825
|
getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
|
|
1812
|
-
setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget)
|
|
1826
|
+
setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget, true, createCoercionContext(evaluationContext))
|
|
1813
1827
|
};
|
|
1814
1828
|
}
|
|
1815
1829
|
async function evaluateCallExpression(node, context) {
|
|
@@ -1965,7 +1979,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
1965
1979
|
property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
|
|
1966
1980
|
};
|
|
1967
1981
|
if (member.superReceiver !== undefined)
|
|
1968
|
-
return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.superReceiver.value);
|
|
1982
|
+
return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context, member.superReceiver.value), context, member.superReceiver.value);
|
|
1969
1983
|
if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") &&
|
|
1970
1984
|
getBoxedPrototype(member.object, context.budget) !== undefined) {
|
|
1971
1985
|
if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
|
|
@@ -1974,7 +1988,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
1974
1988
|
if (typeof member.object === "number" && isNumberMethodName(member.property))
|
|
1975
1989
|
return evaluateNumberMethodCall(node, member.object, member.property, context);
|
|
1976
1990
|
}
|
|
1977
|
-
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);
|
|
1978
1992
|
}
|
|
1979
1993
|
if (typeof member.object === "string" && isStringMethodName(member.property)) {
|
|
1980
1994
|
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
@@ -2022,7 +2036,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
2022
2036
|
return evaluateResolvedCallExpression(node, memberValue, context, member.object);
|
|
2023
2037
|
}
|
|
2024
2038
|
if (isSandboxClosure(member.object)) {
|
|
2025
|
-
const memberValue =
|
|
2039
|
+
const memberValue = await getPropertyValue(member.object, member.property, context);
|
|
2026
2040
|
if (memberValue === undefined) {
|
|
2027
2041
|
throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
|
|
2028
2042
|
}
|
|
@@ -2037,7 +2051,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
2037
2051
|
if (!isIndexableSandboxValue(member.object)) {
|
|
2038
2052
|
throw new TypeError("Attempted to read a property from a non-object value.");
|
|
2039
2053
|
}
|
|
2040
|
-
return evaluateResolvedCallExpression(node,
|
|
2054
|
+
return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
|
|
2041
2055
|
});
|
|
2042
2056
|
}
|
|
2043
2057
|
function evaluatePrimitiveMemberCall(node, receiverType, property, value, context) {
|
|
@@ -2222,7 +2236,8 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
2222
2236
|
if (isFloat32ArrayConstructor(right))
|
|
2223
2237
|
return isFloat32Array(left);
|
|
2224
2238
|
if (isDateConstructor(right))
|
|
2225
|
-
return isSandboxDate(left) &&
|
|
2239
|
+
return (isSandboxDate(left) &&
|
|
2240
|
+
getDatePrototype(left, context.budget, context.compilation?.owner) !== null);
|
|
2226
2241
|
if (isSandboxSetConstructor(right) && isSandboxSet(left)) {
|
|
2227
2242
|
return true;
|
|
2228
2243
|
}
|
|
@@ -2232,17 +2247,21 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
2232
2247
|
if (isGuestClosure(right)) {
|
|
2233
2248
|
if (typeof left !== "object" || left === null)
|
|
2234
2249
|
return false;
|
|
2235
|
-
const
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
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);
|
|
2246
2265
|
}
|
|
2247
2266
|
return false;
|
|
2248
2267
|
case "in":
|
|
@@ -2420,7 +2439,7 @@ async function toNumericPrimitive(value, context) {
|
|
|
2420
2439
|
}
|
|
2421
2440
|
if (isIndexableSandboxValue(value)) {
|
|
2422
2441
|
for (const methodName of ["valueOf", "toString"]) {
|
|
2423
|
-
const method =
|
|
2442
|
+
const method = await getPropertyValue(value, methodName, context);
|
|
2424
2443
|
if (methodName === "toString" && method === undefined && !Object.hasOwn(value, methodName)) {
|
|
2425
2444
|
return toString(value);
|
|
2426
2445
|
}
|
|
@@ -2516,7 +2535,7 @@ function getArrayMemberValue(target, property, context) {
|
|
|
2516
2535
|
}
|
|
2517
2536
|
return getArrayMember(target, property, createArrayMethodOptions(context));
|
|
2518
2537
|
}
|
|
2519
|
-
export function setSandboxProperty(target, property, value, budget, checkInherited = true) {
|
|
2538
|
+
export function setSandboxProperty(target, property, value, budget, checkInherited = true, context) {
|
|
2520
2539
|
if (isSandboxDate(target))
|
|
2521
2540
|
throw new TypeError("Date own properties are not supported.");
|
|
2522
2541
|
if (isGuestHostObject(target)) {
|
|
@@ -2524,6 +2543,11 @@ export function setSandboxProperty(target, property, value, budget, checkInherit
|
|
|
2524
2543
|
return;
|
|
2525
2544
|
}
|
|
2526
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
|
+
}
|
|
2527
2551
|
if (isGuestClosure(target))
|
|
2528
2552
|
target = materializeFunctionProperties(target);
|
|
2529
2553
|
if (isFloat32Array(target)) {
|
|
@@ -2570,7 +2594,8 @@ export function setSandboxProperty(target, property, value, budget, checkInherit
|
|
|
2570
2594
|
defineSandboxProperty(target, key, value);
|
|
2571
2595
|
}
|
|
2572
2596
|
}
|
|
2573
|
-
function setSuperProperty(base, receiver, key, value,
|
|
2597
|
+
function setSuperProperty(base, receiver, key, value, context) {
|
|
2598
|
+
const budget = context.budget;
|
|
2574
2599
|
if (typeof base !== "object" || base === null)
|
|
2575
2600
|
throw new TypeError("Cannot assign a property of null.");
|
|
2576
2601
|
let depth = 0;
|
|
@@ -2581,13 +2606,15 @@ function setSuperProperty(base, receiver, key, value, budget) {
|
|
|
2581
2606
|
const descriptor = properties === undefined ? undefined : Object.getOwnPropertyDescriptor(properties, key);
|
|
2582
2607
|
if (descriptor === undefined)
|
|
2583
2608
|
continue;
|
|
2609
|
+
if (!("value" in descriptor))
|
|
2610
|
+
return writePropertyDescriptor(descriptor, receiver, value, createCoercionContext(context));
|
|
2584
2611
|
if (descriptor.writable !== true)
|
|
2585
2612
|
throw new TypeError(`Cannot assign to read only property '${key}'.`);
|
|
2586
2613
|
break;
|
|
2587
2614
|
}
|
|
2588
2615
|
if (typeof receiver !== "object" || receiver === null)
|
|
2589
2616
|
throw new TypeError("Super assignment requires an object receiver.");
|
|
2590
|
-
setSandboxProperty(receiver, key, value, budget, false);
|
|
2617
|
+
return setSandboxProperty(receiver, key, value, budget, false);
|
|
2591
2618
|
}
|
|
2592
2619
|
function deleteSandboxProperty(target, property) {
|
|
2593
2620
|
if (isGuestHostObject(target))
|
|
@@ -2647,7 +2674,7 @@ function createArrayMethodOptions(context) {
|
|
|
2647
2674
|
budget: context.budget,
|
|
2648
2675
|
context: createCoercionContext(context),
|
|
2649
2676
|
hasProperty: (value, property) => hasSandboxProperty(value, property, context),
|
|
2650
|
-
setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
|
|
2677
|
+
setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget, true, createCoercionContext(context)),
|
|
2651
2678
|
deleteProperty: deleteSandboxProperty,
|
|
2652
2679
|
callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, undefined, thisValue)
|
|
2653
2680
|
};
|
|
@@ -2796,16 +2823,28 @@ async function evaluateObjectSpread(node, context) {
|
|
|
2796
2823
|
}
|
|
2797
2824
|
return { ok: true, value: entries };
|
|
2798
2825
|
}
|
|
2799
|
-
if ((isSandboxClosure(value.value) && !isGuestClosure(value.value)) ||
|
|
2826
|
+
if ((isSandboxClosure(value.value) && !isGuestClosure(value.value)) ||
|
|
2827
|
+
isSandboxPromise(value.value)) {
|
|
2800
2828
|
throw new TypeError(`Cannot spread ${describeObjectSpreadValue(value.value)} into object literal.`);
|
|
2801
2829
|
}
|
|
2802
|
-
const spreadValue = isGuestClosure(value.value)
|
|
2830
|
+
const spreadValue = isGuestClosure(value.value)
|
|
2831
|
+
? (value.value.properties ?? {})
|
|
2832
|
+
: Object(value.value);
|
|
2803
2833
|
const keys = Object.keys(spreadValue);
|
|
2804
2834
|
context.budget.allocateArrayLength(keys.length);
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
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
|
+
}
|
|
2809
2848
|
}
|
|
2810
2849
|
function describeObjectSpreadValue(value) {
|
|
2811
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
|
};
|