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
|
@@ -3408,7 +3408,7 @@ var Parser = class {
|
|
|
3408
3408
|
});
|
|
3409
3409
|
});
|
|
3410
3410
|
}
|
|
3411
|
-
parseFunctionParts(generator, lexicalContext) {
|
|
3411
|
+
parseFunctionParts(generator, lexicalContext, accessor) {
|
|
3412
3412
|
return this.withLexicalContext(lexicalContext, () => {
|
|
3413
3413
|
const params = this.withScope(() => {
|
|
3414
3414
|
const parsed = this.parseArrowParameters();
|
|
@@ -3416,7 +3416,24 @@ var Parser = class {
|
|
|
3416
3416
|
for (const identifier of boundIdentifiers(param)) this.declareBinding(identifier);
|
|
3417
3417
|
return parsed;
|
|
3418
3418
|
});
|
|
3419
|
+
if (accessor === "get" && params.length !== 0)
|
|
3420
|
+
throw new Error("A getter cannot have parameters.");
|
|
3421
|
+
if (accessor === "set" && (params.length !== 1 || params[0]?.type === "RestElement"))
|
|
3422
|
+
throw new Error("A setter must have exactly one non-rest parameter.");
|
|
3423
|
+
const bodyTokenIndex = this.index;
|
|
3419
3424
|
const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
|
|
3425
|
+
if (accessor === "set" && params[0]?.type !== "Identifier") {
|
|
3426
|
+
let directiveTokenIndex = bodyTokenIndex + 1;
|
|
3427
|
+
for (const statement of body.body) {
|
|
3428
|
+
const token = this.tokens[directiveTokenIndex];
|
|
3429
|
+
if (statement.type !== "ExpressionStatement" || statement.expression.type !== "StringLiteral" || token?.type !== "string" || statement.span.start.offset !== token.start.offset || statement.span.end.offset !== token.end.offset) break;
|
|
3430
|
+
if (statement.expression.raw === '"use strict"' || statement.expression.raw === "'use strict'")
|
|
3431
|
+
throw new Error(
|
|
3432
|
+
"A setter with a non-simple parameter cannot contain a use strict directive."
|
|
3433
|
+
);
|
|
3434
|
+
directiveTokenIndex += this.tokens[directiveTokenIndex + 1]?.value === ";" ? 2 : 1;
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3420
3437
|
return { params, body };
|
|
3421
3438
|
});
|
|
3422
3439
|
}
|
|
@@ -3447,8 +3464,14 @@ var Parser = class {
|
|
|
3447
3464
|
}
|
|
3448
3465
|
const generator = this.consumePunctuator("*") !== void 0;
|
|
3449
3466
|
if (async && generator) throw new DisallowedSyntaxError("async generator", methodStart.start);
|
|
3450
|
-
|
|
3451
|
-
|
|
3467
|
+
let accessor;
|
|
3468
|
+
const modifier = this.currentToken();
|
|
3469
|
+
if ((modifier.value === "get" || modifier.value === "set") && this.isObjectMethodStart()) {
|
|
3470
|
+
if (async || generator || modifier.end.offset - modifier.start.offset !== modifier.value.length)
|
|
3471
|
+
throw unexpectedTokenError(modifier);
|
|
3472
|
+
accessor = modifier.value;
|
|
3473
|
+
this.index++;
|
|
3474
|
+
}
|
|
3452
3475
|
const computed = this.consumePunctuator("[") !== void 0;
|
|
3453
3476
|
const key = computed ? this.parseExpression({ allowSequence: true }).node : this.currentToken().type === "string" ? createStringLiteral(this.tokens[this.index++]) : this.currentToken().type === "numeric" ? createNumericLiteral(this.tokens[this.index++]) : this.parseIdentifierName();
|
|
3454
3477
|
if (computed) this.expectPunctuator("]");
|
|
@@ -3456,7 +3479,7 @@ var Parser = class {
|
|
|
3456
3479
|
if (isStatic && name === "prototype") throw new Error("A static class element cannot be named prototype.");
|
|
3457
3480
|
if (this.currentToken().value === "(") {
|
|
3458
3481
|
const constructor = !isStatic && name === "constructor";
|
|
3459
|
-
if (constructor && (async || generator)) throw new Error("A class constructor
|
|
3482
|
+
if (constructor && (async || generator || accessor !== void 0)) throw new Error("A class constructor must be an ordinary method.");
|
|
3460
3483
|
const { params, body } = this.parseFunctionParts(generator, {
|
|
3461
3484
|
newTarget: true,
|
|
3462
3485
|
superProperty: true,
|
|
@@ -3465,7 +3488,7 @@ var Parser = class {
|
|
|
3465
3488
|
return: true,
|
|
3466
3489
|
await: async,
|
|
3467
3490
|
strictAwait: true
|
|
3468
|
-
});
|
|
3491
|
+
}, accessor);
|
|
3469
3492
|
const value2 = this.withFunctionSource({
|
|
3470
3493
|
type: "FunctionExpression",
|
|
3471
3494
|
async,
|
|
@@ -3480,7 +3503,7 @@ var Parser = class {
|
|
|
3480
3503
|
key,
|
|
3481
3504
|
computed,
|
|
3482
3505
|
static: isStatic,
|
|
3483
|
-
kind: constructor ? "constructor" : "method",
|
|
3506
|
+
kind: accessor ?? (constructor ? "constructor" : "method"),
|
|
3484
3507
|
value: value2,
|
|
3485
3508
|
span: createSpan2(start.start, value2.span.end)
|
|
3486
3509
|
};
|
|
@@ -4728,7 +4751,10 @@ var Parser = class {
|
|
|
4728
4751
|
return (propertyToken.type === "identifier" || propertyToken.type === "keyword" || propertyToken.type === "numeric" || propertyToken.type === "string") && this.peekToken(2).type === "punctuator" && this.peekToken(2).value === "(";
|
|
4729
4752
|
}
|
|
4730
4753
|
parseObjectMethod(asyncToken, methodStart) {
|
|
4731
|
-
const { params, body } = this.parseFunctionParts(false,
|
|
4754
|
+
const { params, body } = this.parseFunctionParts(false, {
|
|
4755
|
+
...ordinaryFunctionContext,
|
|
4756
|
+
superProperty: true
|
|
4757
|
+
});
|
|
4732
4758
|
return this.withFunctionSource({
|
|
4733
4759
|
type: "FunctionExpression",
|
|
4734
4760
|
async: asyncToken !== void 0,
|
|
@@ -6527,6 +6553,64 @@ function serializedDateTime(value) {
|
|
|
6527
6553
|
return Number.isNaN(time) ? null : time;
|
|
6528
6554
|
}
|
|
6529
6555
|
|
|
6556
|
+
// packages/safe-js/src/interp/accessors.ts
|
|
6557
|
+
var accessorClosures = /* @__PURE__ */ new WeakMap();
|
|
6558
|
+
var getterAdapters = /* @__PURE__ */ new WeakMap();
|
|
6559
|
+
var setterAdapters = /* @__PURE__ */ new WeakMap();
|
|
6560
|
+
function accessorAdapter(closure, kind) {
|
|
6561
|
+
if (kind === "get") {
|
|
6562
|
+
let adapter2 = getterAdapters.get(closure);
|
|
6563
|
+
if (adapter2 === void 0) {
|
|
6564
|
+
adapter2 = () => void 0;
|
|
6565
|
+
getterAdapters.set(closure, adapter2);
|
|
6566
|
+
accessorClosures.set(adapter2, closure);
|
|
6567
|
+
}
|
|
6568
|
+
return adapter2;
|
|
6569
|
+
}
|
|
6570
|
+
let adapter = setterAdapters.get(closure);
|
|
6571
|
+
if (adapter === void 0) {
|
|
6572
|
+
adapter = () => {
|
|
6573
|
+
throw new TypeError("Accessor writes require sandbox execution.");
|
|
6574
|
+
};
|
|
6575
|
+
setterAdapters.set(closure, adapter);
|
|
6576
|
+
accessorClosures.set(adapter, closure);
|
|
6577
|
+
}
|
|
6578
|
+
return adapter;
|
|
6579
|
+
}
|
|
6580
|
+
function accessorClosure(adapter) {
|
|
6581
|
+
if (adapter === void 0) return void 0;
|
|
6582
|
+
const closure = accessorClosures.get(adapter);
|
|
6583
|
+
if (closure === void 0) throw new TypeError("Native accessors cannot execute in the sandbox.");
|
|
6584
|
+
return closure;
|
|
6585
|
+
}
|
|
6586
|
+
function retainedAccessorClosures(descriptor) {
|
|
6587
|
+
const closures = [];
|
|
6588
|
+
for (const adapter of [descriptor.get, descriptor.set]) {
|
|
6589
|
+
const closure = adapter === void 0 ? void 0 : accessorClosures.get(adapter);
|
|
6590
|
+
if (closure !== void 0) closures.push(closure);
|
|
6591
|
+
}
|
|
6592
|
+
return closures;
|
|
6593
|
+
}
|
|
6594
|
+
function readPropertyDescriptor(descriptor, receiver, context, allowNativeGetter = false) {
|
|
6595
|
+
if ("value" in descriptor) return descriptor.value;
|
|
6596
|
+
if (descriptor.get === void 0) return void 0;
|
|
6597
|
+
const getter = accessorClosures.get(descriptor.get);
|
|
6598
|
+
if (getter === void 0) {
|
|
6599
|
+
if (!allowNativeGetter) throw new TypeError("Native accessors cannot execute in the sandbox.");
|
|
6600
|
+
return Reflect.apply(descriptor.get, receiver, []);
|
|
6601
|
+
}
|
|
6602
|
+
if (context?.invokeClosure === void 0)
|
|
6603
|
+
throw new TypeError("Accessor reads require sandbox execution.");
|
|
6604
|
+
return context.invokeClosure(getter, [], receiver);
|
|
6605
|
+
}
|
|
6606
|
+
function writePropertyDescriptor(descriptor, receiver, value, context) {
|
|
6607
|
+
const setter = accessorClosure(descriptor.set);
|
|
6608
|
+
if (setter === void 0) throw new TypeError("Cannot assign to a getter-only property.");
|
|
6609
|
+
if (context?.invokeClosure === void 0)
|
|
6610
|
+
throw new TypeError("Accessor writes require sandbox execution.");
|
|
6611
|
+
return context.invokeClosure(setter, [value], receiver).then(() => void 0);
|
|
6612
|
+
}
|
|
6613
|
+
|
|
6530
6614
|
// packages/safe-js/src/interp/collection-brands.ts
|
|
6531
6615
|
var sandboxMapBrand = /* @__PURE__ */ Symbol("SandboxMap");
|
|
6532
6616
|
var sandboxSetBrand = /* @__PURE__ */ Symbol("SandboxSet");
|
|
@@ -7317,15 +7401,23 @@ function registerIntrinsicPrototype(budget, prototype, constructor) {
|
|
|
7317
7401
|
...record2,
|
|
7318
7402
|
descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(record2.value)))
|
|
7319
7403
|
}));
|
|
7320
|
-
const unchanged = (before, after) => before !== void 0 && after !== void 0 && Object.is(before.value, after.value) && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
|
|
7321
|
-
intrinsicConstructors.set(
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7404
|
+
const unchanged = (before, after) => before !== void 0 && after !== void 0 && Object.is(before.value, after.value) && before.get === after.get && before.set === after.set && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
|
|
7405
|
+
intrinsicConstructors.set(
|
|
7406
|
+
constructor,
|
|
7407
|
+
() => records.every(({ target, value, descriptors, prototype: parent, explicit }) => {
|
|
7408
|
+
const current = Object.getOwnPropertyDescriptors(value);
|
|
7409
|
+
return getSandboxPrototype(target) === parent && hasExplicitSandboxPrototype(target) === explicit && Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
|
|
7410
|
+
})
|
|
7411
|
+
);
|
|
7412
|
+
budget.setRetainedValues(
|
|
7413
|
+
prototype,
|
|
7414
|
+
() => records.flatMap(({ target, value, descriptors, prototype: parent }) => [
|
|
7415
|
+
...getSandboxPrototype(target) === parent ? [] : [getSandboxPrototype(target)],
|
|
7416
|
+
...Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(
|
|
7417
|
+
([key, descriptor]) => unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value, ...retainedAccessorClosures(descriptor)]
|
|
7418
|
+
)
|
|
7419
|
+
])
|
|
7420
|
+
);
|
|
7329
7421
|
}
|
|
7330
7422
|
function releaseObjectPrototype(budget) {
|
|
7331
7423
|
for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
|
|
@@ -7344,6 +7436,24 @@ function getSandboxPrototype(value, budget) {
|
|
|
7344
7436
|
function hasExplicitSandboxPrototype(value) {
|
|
7345
7437
|
return prototypes.has(value);
|
|
7346
7438
|
}
|
|
7439
|
+
function getSandboxPropertyDescriptor(value, key, budget) {
|
|
7440
|
+
const hostProperties = isSandboxClosure(value) ? value.properties : void 0;
|
|
7441
|
+
if (isSandboxClosure(value) && !isGuestClosure(value))
|
|
7442
|
+
return hostProperties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(hostProperties, key);
|
|
7443
|
+
let current = value;
|
|
7444
|
+
let depth = 0;
|
|
7445
|
+
while (typeof current === "object" && current !== null && (Array.isArray(current) || isPrototypeRecord(current))) {
|
|
7446
|
+
const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
|
|
7447
|
+
const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
|
|
7448
|
+
if (descriptor !== void 0) return descriptor;
|
|
7449
|
+
current = getSandboxPrototype(current, budget);
|
|
7450
|
+
if (current !== null) {
|
|
7451
|
+
budget?.visitNode();
|
|
7452
|
+
assertSandboxDataDepth(++depth);
|
|
7453
|
+
}
|
|
7454
|
+
}
|
|
7455
|
+
return void 0;
|
|
7456
|
+
}
|
|
7347
7457
|
function getSandboxDataProperty(value, key, budget) {
|
|
7348
7458
|
let current = value;
|
|
7349
7459
|
let depth = 0;
|
|
@@ -8907,7 +9017,7 @@ async function callRegexMethod(target, methodName, args, budget, context) {
|
|
|
8907
9017
|
try {
|
|
8908
9018
|
const input = await sandboxString(args[0], budget, context);
|
|
8909
9019
|
if (methodName === "test") {
|
|
8910
|
-
const exec = context?.getProperty === void 0 ? getSandboxDataProperty(target, "exec", budget) : context.getProperty(target, "exec");
|
|
9020
|
+
const exec = context?.getProperty === void 0 ? getSandboxDataProperty(target, "exec", budget) : await context.getProperty(target, "exec");
|
|
8911
9021
|
if (isSandboxClosure(exec)) {
|
|
8912
9022
|
const result = await invokeBuiltinClosure(exec, [input], budget, context, target);
|
|
8913
9023
|
if (result !== null && typeof result !== "object") {
|
|
@@ -9011,6 +9121,7 @@ function functionString(value) {
|
|
|
9011
9121
|
// packages/safe-js/src/interp/string-coercion.ts
|
|
9012
9122
|
var defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
|
|
9013
9123
|
var defaultValueHook = /* @__PURE__ */ Symbol("defaultValueHook");
|
|
9124
|
+
var joiningArrays = /* @__PURE__ */ new WeakSet();
|
|
9014
9125
|
function sandboxNumber(value, budget, context) {
|
|
9015
9126
|
if (value === null || typeof value !== "object") {
|
|
9016
9127
|
if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
|
|
@@ -9025,12 +9136,30 @@ function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set
|
|
|
9025
9136
|
}
|
|
9026
9137
|
return objectToPrimitive(value, budget, context, joining, "string").then((primitive) => budget.allocateString(String(primitive)));
|
|
9027
9138
|
}
|
|
9139
|
+
async function joinSandboxArray(value, length, separator, budget, context, joining = /* @__PURE__ */ new Set()) {
|
|
9140
|
+
if (joiningArrays.has(value)) return "";
|
|
9141
|
+
joiningArrays.add(value);
|
|
9142
|
+
let text = "";
|
|
9143
|
+
const release = retainValues(budget, () => [value, text, separator]);
|
|
9144
|
+
try {
|
|
9145
|
+
for (let index = 0; index < length; index++) {
|
|
9146
|
+
budget.visitNode();
|
|
9147
|
+
const element = await readCoercionProperty(value, String(index), context);
|
|
9148
|
+
const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
|
|
9149
|
+
text = budget.allocateString(text + (index === 0 ? "" : separator) + part);
|
|
9150
|
+
}
|
|
9151
|
+
return text;
|
|
9152
|
+
} finally {
|
|
9153
|
+
release();
|
|
9154
|
+
joiningArrays.delete(value);
|
|
9155
|
+
}
|
|
9156
|
+
}
|
|
9028
9157
|
async function objectToPrimitive(value, budget, context, joining, hint) {
|
|
9029
9158
|
const leaveCall = budget.enterCall();
|
|
9030
9159
|
try {
|
|
9031
9160
|
budget.visitNode();
|
|
9032
9161
|
for (const name of hint === "string" ? ["toString", "valueOf"] : ["valueOf", "toString"]) {
|
|
9033
|
-
const hook = conversionHook(value, name, budget);
|
|
9162
|
+
const hook = await conversionHook(value, name, budget, context);
|
|
9034
9163
|
let result;
|
|
9035
9164
|
if (hook === defaultStringHook) {
|
|
9036
9165
|
result = await defaultToString(value, budget, context, joining);
|
|
@@ -9050,7 +9179,7 @@ async function objectToPrimitive(value, budget, context, joining, hint) {
|
|
|
9050
9179
|
leaveCall();
|
|
9051
9180
|
}
|
|
9052
9181
|
}
|
|
9053
|
-
function conversionHook(value, name, budget) {
|
|
9182
|
+
function conversionHook(value, name, budget, context) {
|
|
9054
9183
|
const implicitBuiltin = !hasExplicitSandboxPrototype(value) && (Array.isArray(value) || isSandboxDate(value) || isFloat32Array(value) || sandboxErrorTypes.has(value) || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxCollectionIterator(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxGenerator(value) || isGuestHostObject(value));
|
|
9055
9184
|
let current = value;
|
|
9056
9185
|
let depth = 0;
|
|
@@ -9058,9 +9187,7 @@ function conversionHook(value, name, budget) {
|
|
|
9058
9187
|
const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
|
|
9059
9188
|
const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, name);
|
|
9060
9189
|
if (descriptor !== void 0) {
|
|
9061
|
-
|
|
9062
|
-
throw new TypeError("String conversion requires sandbox data properties.");
|
|
9063
|
-
return descriptor.value;
|
|
9190
|
+
return readPropertyDescriptor(descriptor, value, context);
|
|
9064
9191
|
}
|
|
9065
9192
|
const parent = getSandboxPrototype(current, budget);
|
|
9066
9193
|
if (current === value && (implicitBuiltin || parent === null && !hasExplicitSandboxPrototype(value))) {
|
|
@@ -9079,7 +9206,8 @@ async function defaultToString(value, budget, context, joining) {
|
|
|
9079
9206
|
if (isSandboxClosure(value)) return budget.allocateString(functionString(value));
|
|
9080
9207
|
if (isSandboxMap(value)) return "[object Map]";
|
|
9081
9208
|
if (isSandboxSet(value)) return "[object Set]";
|
|
9082
|
-
if (isSandboxCollectionIterator(value))
|
|
9209
|
+
if (isSandboxCollectionIterator(value))
|
|
9210
|
+
return collectionIteratorState(value).collectionKind === "map" ? "[object Map Iterator]" : "[object Set Iterator]";
|
|
9083
9211
|
if (isSandboxGenerator(value)) return "[object Generator]";
|
|
9084
9212
|
if (isSandboxRegex(value)) {
|
|
9085
9213
|
return budget.allocateString(
|
|
@@ -9089,35 +9217,20 @@ async function defaultToString(value, budget, context, joining) {
|
|
|
9089
9217
|
if (isSandboxDate(value)) return budget.allocateString(dateString(value));
|
|
9090
9218
|
if (Array.isArray(value) || isFloat32Array(value)) {
|
|
9091
9219
|
if (Object.hasOwn(value, "join")) {
|
|
9092
|
-
const join =
|
|
9220
|
+
const join = await readCoercionProperty(value, "join", context);
|
|
9093
9221
|
if (!isSandboxClosure(join))
|
|
9094
9222
|
return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
|
|
9095
9223
|
return invokeBuiltinClosure(join, [], budget, context, value);
|
|
9096
9224
|
}
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
let text = "";
|
|
9100
|
-
const release = retainValues(budget, () => [text]);
|
|
9101
|
-
try {
|
|
9102
|
-
const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
|
|
9103
|
-
for (let index = 0; index < length; index++) {
|
|
9104
|
-
budget.visitNode();
|
|
9105
|
-
const element = ownDataValue(value, String(index));
|
|
9106
|
-
const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
|
|
9107
|
-
text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
|
|
9108
|
-
}
|
|
9109
|
-
return text;
|
|
9110
|
-
} finally {
|
|
9111
|
-
release();
|
|
9112
|
-
joining.delete(value);
|
|
9113
|
-
}
|
|
9225
|
+
const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
|
|
9226
|
+
return joinSandboxArray(value, length, ",", budget, context, joining);
|
|
9114
9227
|
}
|
|
9115
9228
|
if (sandboxErrorTypes.has(value)) {
|
|
9116
|
-
const nameValue =
|
|
9229
|
+
const nameValue = await readCoercionProperty(value, "name", context);
|
|
9117
9230
|
const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
|
|
9118
9231
|
const release = retainValues(budget, () => [name]);
|
|
9119
9232
|
try {
|
|
9120
|
-
const messageValue =
|
|
9233
|
+
const messageValue = await readCoercionProperty(value, "message", context);
|
|
9121
9234
|
const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
|
|
9122
9235
|
return name === "" ? message : message === "" ? name : `${name}: ${message}`;
|
|
9123
9236
|
} finally {
|
|
@@ -9126,12 +9239,153 @@ async function defaultToString(value, budget, context, joining) {
|
|
|
9126
9239
|
}
|
|
9127
9240
|
return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
|
|
9128
9241
|
}
|
|
9129
|
-
function
|
|
9242
|
+
function readCoercionProperty(value, name, context) {
|
|
9243
|
+
if (context?.getProperty !== void 0) return context.getProperty(value, name);
|
|
9130
9244
|
const descriptor = Object.getOwnPropertyDescriptor(value, name);
|
|
9131
|
-
|
|
9132
|
-
|
|
9245
|
+
return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
|
|
9246
|
+
}
|
|
9247
|
+
|
|
9248
|
+
// packages/safe-js/src/interp/globals/object.ts
|
|
9249
|
+
function createObjectGlobal(methods, budget) {
|
|
9250
|
+
const construct = ([value]) => {
|
|
9251
|
+
if (value === null || value === void 0) {
|
|
9252
|
+
budget.chargeDataUsage(1);
|
|
9253
|
+
return /* @__PURE__ */ Object.create(null);
|
|
9254
|
+
}
|
|
9255
|
+
if (typeof value !== "object") {
|
|
9256
|
+
const box = createSandboxBox(value);
|
|
9257
|
+
budget.chargeDataUsage(measureSandboxData([box]));
|
|
9258
|
+
return box;
|
|
9259
|
+
}
|
|
9260
|
+
return value;
|
|
9261
|
+
};
|
|
9262
|
+
const constructor = createSandboxClosure({
|
|
9263
|
+
guest: true,
|
|
9264
|
+
sandbox: true,
|
|
9265
|
+
name: "Object",
|
|
9266
|
+
length: 1,
|
|
9267
|
+
call: construct,
|
|
9268
|
+
construct: (args, context) => {
|
|
9269
|
+
if (context?.newTarget === void 0 || context.newTarget === constructor)
|
|
9270
|
+
return construct(args);
|
|
9271
|
+
const value = construct([]);
|
|
9272
|
+
const prototype2 = context.getProperty(context.newTarget, "prototype");
|
|
9273
|
+
const finish = (prototype3) => {
|
|
9274
|
+
if (typeof prototype3 === "object" && prototype3 !== null)
|
|
9275
|
+
setSandboxPrototype(value, prototype3, budget);
|
|
9276
|
+
return value;
|
|
9277
|
+
};
|
|
9278
|
+
return prototype2 instanceof Promise ? prototype2.then(finish) : finish(prototype2);
|
|
9279
|
+
}
|
|
9280
|
+
});
|
|
9281
|
+
const properties = materializeFunctionProperties(constructor);
|
|
9282
|
+
const prototype = properties.prototype;
|
|
9283
|
+
Object.defineProperty(properties, "prototype", { writable: false });
|
|
9284
|
+
for (const [name, method] of Object.entries(methods)) {
|
|
9285
|
+
Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
|
|
9286
|
+
}
|
|
9287
|
+
const prototypeMethods = {
|
|
9288
|
+
toString: createSandboxClosure({
|
|
9289
|
+
sandbox: true,
|
|
9290
|
+
name: "toString",
|
|
9291
|
+
length: 0,
|
|
9292
|
+
call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
|
|
9293
|
+
}),
|
|
9294
|
+
valueOf: createSandboxClosure({
|
|
9295
|
+
sandbox: true,
|
|
9296
|
+
name: "valueOf",
|
|
9297
|
+
length: 0,
|
|
9298
|
+
call: (_args, context) => {
|
|
9299
|
+
const value = requireReceiver(context?.thisValue);
|
|
9300
|
+
return construct([value]);
|
|
9301
|
+
}
|
|
9302
|
+
}),
|
|
9303
|
+
hasOwnProperty: createSandboxClosure({
|
|
9304
|
+
sandbox: true,
|
|
9305
|
+
name: "hasOwnProperty",
|
|
9306
|
+
length: 1,
|
|
9307
|
+
call: async ([key], context) => hasOwnSandboxProperty(
|
|
9308
|
+
requireReceiver(context?.thisValue),
|
|
9309
|
+
await sandboxString(key, budget, context),
|
|
9310
|
+
false
|
|
9311
|
+
)
|
|
9312
|
+
}),
|
|
9313
|
+
propertyIsEnumerable: createSandboxClosure({
|
|
9314
|
+
sandbox: true,
|
|
9315
|
+
name: "propertyIsEnumerable",
|
|
9316
|
+
length: 1,
|
|
9317
|
+
call: async ([key], context) => hasOwnSandboxProperty(
|
|
9318
|
+
requireReceiver(context?.thisValue),
|
|
9319
|
+
await sandboxString(key, budget, context),
|
|
9320
|
+
true
|
|
9321
|
+
)
|
|
9322
|
+
}),
|
|
9323
|
+
isPrototypeOf: createSandboxClosure({
|
|
9324
|
+
sandbox: true,
|
|
9325
|
+
name: "isPrototypeOf",
|
|
9326
|
+
length: 1,
|
|
9327
|
+
call: ([value], context) => {
|
|
9328
|
+
if (typeof value !== "object" || value === null) return false;
|
|
9329
|
+
const receiver = requireReceiver(context?.thisValue);
|
|
9330
|
+
let depth = 0;
|
|
9331
|
+
for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
|
|
9332
|
+
budget.visitNode();
|
|
9333
|
+
assertSandboxDataDepth(depth++);
|
|
9334
|
+
if (current === receiver) return true;
|
|
9335
|
+
}
|
|
9336
|
+
return false;
|
|
9337
|
+
}
|
|
9338
|
+
})
|
|
9339
|
+
};
|
|
9340
|
+
for (const [name, method] of Object.entries(prototypeMethods)) {
|
|
9341
|
+
Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
|
|
9342
|
+
}
|
|
9343
|
+
markDescriptorObject(prototype);
|
|
9344
|
+
installObjectPrototype(budget, prototype, constructor);
|
|
9345
|
+
return constructor;
|
|
9346
|
+
}
|
|
9347
|
+
function requireReceiver(value) {
|
|
9348
|
+
if (value === null || value === void 0)
|
|
9349
|
+
throw new TypeError("Object method requires a non-null receiver.");
|
|
9350
|
+
return value;
|
|
9351
|
+
}
|
|
9352
|
+
function hasOwnSandboxProperty(value, key, enumerable) {
|
|
9353
|
+
requireReceiver(value);
|
|
9354
|
+
if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
|
|
9355
|
+
let properties;
|
|
9356
|
+
if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
|
|
9357
|
+
else if (isSandboxClosure(value)) {
|
|
9358
|
+
if (key === "length" || key === "name") return !enumerable;
|
|
9359
|
+
properties = value.properties ?? /* @__PURE__ */ Object.create(null);
|
|
9360
|
+
} else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
|
|
9361
|
+
return false;
|
|
9362
|
+
else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
|
|
9363
|
+
else properties = Object(value);
|
|
9364
|
+
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
9365
|
+
return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
|
|
9366
|
+
}
|
|
9367
|
+
function typeTag(value) {
|
|
9368
|
+
if (isSandboxBox(value)) value = boxedValue(value);
|
|
9369
|
+
if (value === void 0) return "Undefined";
|
|
9370
|
+
if (value === null) return "Null";
|
|
9371
|
+
if (typeof value === "string") return "String";
|
|
9372
|
+
if (typeof value === "number") return "Number";
|
|
9373
|
+
if (typeof value === "boolean") return "Boolean";
|
|
9374
|
+
if (isSandboxClosure(value)) {
|
|
9375
|
+
while (value.boundTarget !== void 0) value = value.boundTarget;
|
|
9376
|
+
return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
|
|
9133
9377
|
}
|
|
9134
|
-
return
|
|
9378
|
+
if (Array.isArray(value)) return "Array";
|
|
9379
|
+
if (isSandboxDate(value)) return "Date";
|
|
9380
|
+
if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
|
|
9381
|
+
if (isSandboxRegex(value)) return "RegExp";
|
|
9382
|
+
if (isSandboxMap(value)) return "Map";
|
|
9383
|
+
if (isSandboxSet(value)) return "Set";
|
|
9384
|
+
if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "Map Iterator" : "Set Iterator";
|
|
9385
|
+
if (isSandboxPromise(value)) return "Promise";
|
|
9386
|
+
if (isSandboxGenerator(value)) return "Generator";
|
|
9387
|
+
if (isFloat32Array(value)) return "Float32Array";
|
|
9388
|
+
return "Object";
|
|
9135
9389
|
}
|
|
9136
9390
|
|
|
9137
9391
|
// packages/safe-js/src/interp/property-key.ts
|
|
@@ -9514,12 +9768,34 @@ async function bindArrayPattern(pattern, value, context, evaluateNode2) {
|
|
|
9514
9768
|
if (!Array.isArray(value)) {
|
|
9515
9769
|
throw new TypeError("Array catch bindings require an array value.");
|
|
9516
9770
|
}
|
|
9771
|
+
let cursor = 0;
|
|
9772
|
+
let done = false;
|
|
9773
|
+
const next = async () => {
|
|
9774
|
+
if (done || cursor >= value.length) {
|
|
9775
|
+
done = true;
|
|
9776
|
+
return { done: true, value: void 0 };
|
|
9777
|
+
}
|
|
9778
|
+
const key = cursor++;
|
|
9779
|
+
return {
|
|
9780
|
+
done: false,
|
|
9781
|
+
value: context.getProperty === void 0 ? getSandboxDataProperty(value, key, context.budget) : await context.getProperty(value, key)
|
|
9782
|
+
};
|
|
9783
|
+
};
|
|
9517
9784
|
for (let index = 0; index < pattern.elements.length; index += 1) {
|
|
9518
9785
|
const element = pattern.elements[index];
|
|
9519
9786
|
if (element === null) {
|
|
9787
|
+
await next();
|
|
9520
9788
|
continue;
|
|
9521
9789
|
}
|
|
9522
|
-
|
|
9790
|
+
let elementValue;
|
|
9791
|
+
if (element.type === "RestElement") {
|
|
9792
|
+
const rest = [];
|
|
9793
|
+
for (let entry = await next(); !entry.done; entry = await next()) {
|
|
9794
|
+
context.budget.allocateArrayLength(rest.length + 1);
|
|
9795
|
+
rest.push(entry.value);
|
|
9796
|
+
}
|
|
9797
|
+
elementValue = rest;
|
|
9798
|
+
} else elementValue = (await next()).value;
|
|
9523
9799
|
const binding = await bindPattern(element, elementValue, context, evaluateNode2);
|
|
9524
9800
|
if (!binding.ok) {
|
|
9525
9801
|
return binding;
|
|
@@ -9534,7 +9810,7 @@ async function bindObjectPattern(pattern, value, context, evaluateNode2) {
|
|
|
9534
9810
|
const excludedKeys = /* @__PURE__ */ new Set();
|
|
9535
9811
|
for (const property of pattern.properties) {
|
|
9536
9812
|
if (property.type === "RestElement") {
|
|
9537
|
-
const restValue = copyObjectRest(value, excludedKeys);
|
|
9813
|
+
const restValue = await copyObjectRest(value, excludedKeys, context);
|
|
9538
9814
|
const binding2 = await bindPattern(property, restValue, context, evaluateNode2);
|
|
9539
9815
|
if (!binding2.ok) {
|
|
9540
9816
|
return binding2;
|
|
@@ -9548,7 +9824,7 @@ async function bindObjectPattern(pattern, value, context, evaluateNode2) {
|
|
|
9548
9824
|
excludedKeys.add(String(key.value));
|
|
9549
9825
|
const binding = await bindPattern(
|
|
9550
9826
|
property.value,
|
|
9551
|
-
context.getProperty === void 0 ? getSandboxDataProperty(value, key.value, context.budget) : context.getProperty(value, key.value),
|
|
9827
|
+
context.getProperty === void 0 ? getSandboxDataProperty(value, key.value, context.budget) : await context.getProperty(value, key.value),
|
|
9552
9828
|
context,
|
|
9553
9829
|
evaluateNode2
|
|
9554
9830
|
);
|
|
@@ -9592,12 +9868,18 @@ function getStaticPropertyKey(property) {
|
|
|
9592
9868
|
throw new TypeError(`Unsupported catch binding property key '${property.type}'.`);
|
|
9593
9869
|
}
|
|
9594
9870
|
}
|
|
9595
|
-
function copyObjectRest(value, excludedKeys) {
|
|
9871
|
+
async function copyObjectRest(value, excludedKeys, context) {
|
|
9596
9872
|
const rest = /* @__PURE__ */ Object.create(null);
|
|
9597
|
-
|
|
9598
|
-
|
|
9873
|
+
const release = retainValues(context.budget, () => [value, rest]);
|
|
9874
|
+
try {
|
|
9875
|
+
for (const key of ownEnumerableSandboxKeys(value)) {
|
|
9876
|
+
if (excludedKeys.has(key) || !hasOwnSandboxProperty(value, key, true)) continue;
|
|
9877
|
+
rest[key] = context.getProperty === void 0 ? getSandboxDataProperty(value, key, context.budget) : await context.getProperty(value, key);
|
|
9878
|
+
}
|
|
9879
|
+
return rest;
|
|
9880
|
+
} finally {
|
|
9881
|
+
release();
|
|
9599
9882
|
}
|
|
9600
|
-
return rest;
|
|
9601
9883
|
}
|
|
9602
9884
|
|
|
9603
9885
|
// packages/safe-js/src/interp/running-state.ts
|
|
@@ -9673,6 +9955,18 @@ function getSandboxIterator(value, budget, context) {
|
|
|
9673
9955
|
if (isSandboxSet(value)) {
|
|
9674
9956
|
return collectionIterator(value.values);
|
|
9675
9957
|
}
|
|
9958
|
+
if (Array.isArray(value) && context?.getProperty !== void 0) {
|
|
9959
|
+
let index = 0;
|
|
9960
|
+
return {
|
|
9961
|
+
asynchronous: true,
|
|
9962
|
+
snapshotIndex: () => index,
|
|
9963
|
+
next: async () => {
|
|
9964
|
+
if (index >= value.length) return { done: true, value: void 0 };
|
|
9965
|
+
budget?.visitNode();
|
|
9966
|
+
return { done: false, value: await context.getProperty(value, index++) };
|
|
9967
|
+
}
|
|
9968
|
+
};
|
|
9969
|
+
}
|
|
9676
9970
|
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
9677
9971
|
return void 0;
|
|
9678
9972
|
}
|
|
@@ -10067,7 +10361,7 @@ async function callPromiseClosure(callback, args, thisValue, budget, context) {
|
|
|
10067
10361
|
const values = args.map(
|
|
10068
10362
|
(value) => value instanceof Error && !(value instanceof SandboxError) ? coerceThrownValue(value, budget, stack) : value
|
|
10069
10363
|
);
|
|
10070
|
-
let result = callback.call(values, { stack, thisValue });
|
|
10364
|
+
let result = callback.call(values, { ...context, stack, thisValue, newTarget: void 0 });
|
|
10071
10365
|
if (callback.async !== true) result = await result;
|
|
10072
10366
|
else if (isPromiseLike(result)) result = createSandboxPromise(Promise.resolve(result));
|
|
10073
10367
|
if (isSandboxPromise(result) && result.synchronousPrefix !== void 0) {
|
|
@@ -10094,11 +10388,11 @@ function getPromisePrototype(budget) {
|
|
|
10094
10388
|
target.promise.then(
|
|
10095
10389
|
(value) => {
|
|
10096
10390
|
consumeSettledHostCall(target);
|
|
10097
|
-
return runPromiseReaction(onFulfilled, value, "fulfilled", budget, chained);
|
|
10391
|
+
return runPromiseReaction(onFulfilled, value, "fulfilled", budget, chained, context);
|
|
10098
10392
|
},
|
|
10099
10393
|
(reason) => {
|
|
10100
10394
|
consumeSettledHostCall(target);
|
|
10101
|
-
return runPromiseReaction(onRejected, reason, "rejected", budget, chained);
|
|
10395
|
+
return runPromiseReaction(onRejected, reason, "rejected", budget, chained, context);
|
|
10102
10396
|
}
|
|
10103
10397
|
)
|
|
10104
10398
|
);
|
|
@@ -10110,12 +10404,18 @@ function getPromisePrototype(budget) {
|
|
|
10110
10404
|
sandbox: true,
|
|
10111
10405
|
call: ([onRejected], context) => {
|
|
10112
10406
|
const target = context?.thisValue;
|
|
10113
|
-
const
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10407
|
+
const invoke = (then2) => {
|
|
10408
|
+
if (!isSandboxClosure(then2))
|
|
10409
|
+
throw new TypeError("Promise.catch requires a callable then.");
|
|
10410
|
+
return then2.call([void 0, onRejected], {
|
|
10411
|
+
...context,
|
|
10412
|
+
stack: context?.stack ?? [],
|
|
10413
|
+
thisValue: target,
|
|
10414
|
+
newTarget: void 0
|
|
10415
|
+
});
|
|
10416
|
+
};
|
|
10417
|
+
const then = readPromiseReceiverProperty(target, "then", prototype, context);
|
|
10418
|
+
return then instanceof Promise ? then.then(invoke) : invoke(then);
|
|
10119
10419
|
},
|
|
10120
10420
|
name: "catch"
|
|
10121
10421
|
}),
|
|
@@ -10126,46 +10426,57 @@ function getPromisePrototype(budget) {
|
|
|
10126
10426
|
if (typeof target !== "object" || target === null) {
|
|
10127
10427
|
throw new TypeError("Promise.finally requires an object receiver.");
|
|
10128
10428
|
}
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
}
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
10164
|
-
|
|
10165
|
-
}
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10429
|
+
const invoke = (then) => {
|
|
10430
|
+
if (!isSandboxClosure(then))
|
|
10431
|
+
throw new TypeError("Promise.finally requires a callable then.");
|
|
10432
|
+
const handlers = isSandboxClosure(onFinally) ? ["fulfilled", "rejected"].map(
|
|
10433
|
+
(state) => createSandboxClosure({
|
|
10434
|
+
sandbox: true,
|
|
10435
|
+
retainedValues: () => [onFinally],
|
|
10436
|
+
call: async ([value]) => {
|
|
10437
|
+
const result = await callPromiseClosure(
|
|
10438
|
+
onFinally,
|
|
10439
|
+
[],
|
|
10440
|
+
void 0,
|
|
10441
|
+
budget,
|
|
10442
|
+
context
|
|
10443
|
+
);
|
|
10444
|
+
const pending = isSandboxPromise(result) && getPromiseMember("constructor", budget) === intrinsicPromiseConstructors.get(budget) ? result : createSandboxPromise(resolveSandboxValue(result, { budget }));
|
|
10445
|
+
const cleanupThen = getPromiseMember("then", budget);
|
|
10446
|
+
if (!isSandboxClosure(cleanupThen))
|
|
10447
|
+
throw new TypeError("Promise cleanup requires a callable then.");
|
|
10448
|
+
return callPromiseClosure(
|
|
10449
|
+
cleanupThen,
|
|
10450
|
+
[
|
|
10451
|
+
createSandboxClosure({
|
|
10452
|
+
sandbox: true,
|
|
10453
|
+
retainedValues: () => [value],
|
|
10454
|
+
call: () => {
|
|
10455
|
+
if (state === "rejected") throw value;
|
|
10456
|
+
return value;
|
|
10457
|
+
}
|
|
10458
|
+
})
|
|
10459
|
+
],
|
|
10460
|
+
pending,
|
|
10461
|
+
budget,
|
|
10462
|
+
context
|
|
10463
|
+
);
|
|
10464
|
+
}
|
|
10465
|
+
})
|
|
10466
|
+
) : [onFinally, onFinally];
|
|
10467
|
+
return then.call(handlers, {
|
|
10468
|
+
...context,
|
|
10469
|
+
stack: context?.stack ?? [],
|
|
10470
|
+
thisValue: target,
|
|
10471
|
+
newTarget: void 0
|
|
10472
|
+
});
|
|
10473
|
+
};
|
|
10474
|
+
const finish = () => {
|
|
10475
|
+
const then = readPromiseReceiverProperty(target, "then", prototype, context);
|
|
10476
|
+
return then instanceof Promise ? then.then(invoke) : invoke(then);
|
|
10477
|
+
};
|
|
10478
|
+
const validation = validatePromiseConstructorProperty(target, prototype, context);
|
|
10479
|
+
return validation instanceof Promise ? validation.then(finish) : finish();
|
|
10169
10480
|
},
|
|
10170
10481
|
name: "finally"
|
|
10171
10482
|
})
|
|
@@ -10176,15 +10487,19 @@ function getPromisePrototype(budget) {
|
|
|
10176
10487
|
promisePrototypes.set(budget, prototype);
|
|
10177
10488
|
return prototype;
|
|
10178
10489
|
}
|
|
10179
|
-
function readPromiseReceiverProperty(receiver, property, prototype) {
|
|
10490
|
+
function readPromiseReceiverProperty(receiver, property, prototype, context) {
|
|
10491
|
+
if (!isSandboxPromise(receiver) && context?.getProperty !== void 0)
|
|
10492
|
+
return context.getProperty(receiver, property);
|
|
10180
10493
|
const properties = isSandboxPromise(receiver) ? prototype : isSandboxClosure(receiver) ? receiver.properties : receiver;
|
|
10181
10494
|
return typeof properties === "object" && properties !== null && Object.hasOwn(properties, property) ? properties[property] : void 0;
|
|
10182
10495
|
}
|
|
10183
|
-
function validatePromiseConstructorProperty(receiver, prototype) {
|
|
10184
|
-
const
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
}
|
|
10496
|
+
function validatePromiseConstructorProperty(receiver, prototype, context) {
|
|
10497
|
+
const validate = (constructor2) => {
|
|
10498
|
+
if (constructor2 !== void 0 && (typeof constructor2 !== "object" || constructor2 === null))
|
|
10499
|
+
throw new TypeError("Promise constructor property must be an object.");
|
|
10500
|
+
};
|
|
10501
|
+
const constructor = readPromiseReceiverProperty(receiver, "constructor", prototype, context);
|
|
10502
|
+
return constructor instanceof Promise ? constructor.then(validate) : validate(constructor);
|
|
10188
10503
|
}
|
|
10189
10504
|
async function settleIterable(iterable, method, budget, constructor, context) {
|
|
10190
10505
|
const capability = await createPromiseCapability(constructor, budget, context);
|
|
@@ -10219,7 +10534,7 @@ async function settleIterable(iterable, method, budget, constructor, context) {
|
|
|
10219
10534
|
}
|
|
10220
10535
|
};
|
|
10221
10536
|
try {
|
|
10222
|
-
const promiseResolve = readPromiseReceiverProperty(constructor, "resolve", prototype);
|
|
10537
|
+
const promiseResolve = await readPromiseReceiverProperty(constructor, "resolve", prototype, context);
|
|
10223
10538
|
if (!isSandboxClosure(promiseResolve))
|
|
10224
10539
|
throw new TypeError("Promise constructor requires a callable resolve.");
|
|
10225
10540
|
const iterator = getSandboxIterator(iterable, budget, context);
|
|
@@ -10269,7 +10584,7 @@ async function settleIterable(iterable, method, budget, constructor, context) {
|
|
|
10269
10584
|
});
|
|
10270
10585
|
});
|
|
10271
10586
|
remaining++;
|
|
10272
|
-
const then = readPromiseReceiverProperty(entry, "then", prototype);
|
|
10587
|
+
const then = await readPromiseReceiverProperty(entry, "then", prototype, context);
|
|
10273
10588
|
if (!isSandboxClosure(then))
|
|
10274
10589
|
throw new TypeError("Promise resolver result requires a callable then.");
|
|
10275
10590
|
await callPromiseClosure(then, handlers, entry, budget, context);
|
|
@@ -10356,7 +10671,11 @@ function resolveSandboxValueNow(value, options) {
|
|
|
10356
10671
|
}
|
|
10357
10672
|
);
|
|
10358
10673
|
}
|
|
10359
|
-
const then = getThenable(value);
|
|
10674
|
+
const then = getThenable(value, options.budget);
|
|
10675
|
+
if (then instanceof Promise)
|
|
10676
|
+
return then.then(
|
|
10677
|
+
(method) => method === void 0 ? budgetIfNeeded(value, options.budget) : resolveThenable(value, method, options)
|
|
10678
|
+
);
|
|
10360
10679
|
if (then !== void 0) {
|
|
10361
10680
|
return resolveThenable(value, then, options);
|
|
10362
10681
|
}
|
|
@@ -10376,7 +10695,7 @@ function resolveThenable(value, then, options) {
|
|
|
10376
10695
|
try {
|
|
10377
10696
|
if (settlement.state === "fulfilled") {
|
|
10378
10697
|
resolve(
|
|
10379
|
-
|
|
10698
|
+
requiresPromiseResolution(settlement.value, options.budget) ? resolveSandboxValueNow(settlement.value, options) : budgetIfNeeded(settlement.value, options.budget)
|
|
10380
10699
|
);
|
|
10381
10700
|
} else {
|
|
10382
10701
|
reject(budgetIfNeeded(settlement.value, options.budget));
|
|
@@ -10432,7 +10751,7 @@ function resolveThenable(value, then, options) {
|
|
|
10432
10751
|
).catch(reject);
|
|
10433
10752
|
});
|
|
10434
10753
|
}
|
|
10435
|
-
function runPromiseReaction(handler, value, state, budget, self) {
|
|
10754
|
+
function runPromiseReaction(handler, value, state, budget, self, context) {
|
|
10436
10755
|
return new Promise((resolve, reject) => {
|
|
10437
10756
|
if (state === "rejected" && value instanceof SandboxError && (value.code === "budgetExceeded" || value.code === "reentry")) {
|
|
10438
10757
|
reject(value);
|
|
@@ -10446,14 +10765,14 @@ function runPromiseReaction(handler, value, state, budget, self) {
|
|
|
10446
10765
|
reject(
|
|
10447
10766
|
createSubsetErrorValue("TypeError", "Promise cannot resolve to itself.", [], budget)
|
|
10448
10767
|
);
|
|
10449
|
-
} else if (
|
|
10768
|
+
} else if (requiresPromiseResolution(result, budget)) {
|
|
10450
10769
|
resolve(resolvePromiseResult(result, budget, self));
|
|
10451
10770
|
} else {
|
|
10452
10771
|
resolve(budgetSandboxValue(result, budget));
|
|
10453
10772
|
}
|
|
10454
10773
|
};
|
|
10455
10774
|
if (isSandboxClosure(handler)) {
|
|
10456
|
-
callInPromiseJob(handler, [argument], void 0, { fulfilled, rejected: reject }).catch(
|
|
10775
|
+
callInPromiseJob(handler, [argument], void 0, { fulfilled, rejected: reject }, context).catch(
|
|
10457
10776
|
reject
|
|
10458
10777
|
);
|
|
10459
10778
|
} else {
|
|
@@ -10464,10 +10783,10 @@ function runPromiseReaction(handler, value, state, budget, self) {
|
|
|
10464
10783
|
}
|
|
10465
10784
|
});
|
|
10466
10785
|
}
|
|
10467
|
-
function callInPromiseJob(handler, args, thisValue = void 0, completion) {
|
|
10786
|
+
function callInPromiseJob(handler, args, thisValue = void 0, completion, context) {
|
|
10468
10787
|
return runPromiseJob(async () => {
|
|
10469
10788
|
try {
|
|
10470
|
-
let result = handler.call(args, { stack: [], thisValue });
|
|
10789
|
+
let result = handler.call(args, { ...context, stack: [], thisValue, newTarget: void 0 });
|
|
10471
10790
|
if (handler.async !== true) result = await result;
|
|
10472
10791
|
if (isSandboxPromise(result) && result.synchronousPrefix !== void 0) {
|
|
10473
10792
|
await result.synchronousPrefix;
|
|
@@ -10500,7 +10819,7 @@ function resolvePromiseResult(result, budget, self) {
|
|
|
10500
10819
|
settled = true;
|
|
10501
10820
|
try {
|
|
10502
10821
|
if (state === "rejected") reject(budgetSandboxValue(value, budget));
|
|
10503
|
-
else if (
|
|
10822
|
+
else if (requiresPromiseResolution(value, budget)) {
|
|
10504
10823
|
resolve(resolvePromiseResult(value, budget, self));
|
|
10505
10824
|
} else {
|
|
10506
10825
|
resolve(budgetSandboxValue(value, budget));
|
|
@@ -10548,11 +10867,23 @@ function resolvePromiseResult(result, budget, self) {
|
|
|
10548
10867
|
function isSelfResolution(result, self) {
|
|
10549
10868
|
return self !== void 0 && (result === self || isSandboxPromise(result) && result.promise === self.promise);
|
|
10550
10869
|
}
|
|
10551
|
-
function
|
|
10870
|
+
function requiresPromiseResolution(value, budget) {
|
|
10871
|
+
if (isSandboxPromise(value)) return true;
|
|
10872
|
+
const descriptor = getSandboxPropertyDescriptor(value, "then", budget);
|
|
10873
|
+
return descriptor !== void 0 && (!("value" in descriptor) || isSandboxClosure(descriptor.value));
|
|
10874
|
+
}
|
|
10875
|
+
function getThenable(value, budget) {
|
|
10552
10876
|
if (typeof value !== "object" || value === null || isSandboxPromise(value)) {
|
|
10553
10877
|
return void 0;
|
|
10554
10878
|
}
|
|
10555
|
-
const
|
|
10879
|
+
const descriptor = getSandboxPropertyDescriptor(value, "then", budget);
|
|
10880
|
+
if (descriptor !== void 0 && !("value" in descriptor)) {
|
|
10881
|
+
const getter = accessorClosure(descriptor.get);
|
|
10882
|
+
if (getter === void 0) return void 0;
|
|
10883
|
+
const result = budget === void 0 ? getter.call([], { stack: [], thisValue: value }) : callPromiseClosure(getter, [], value, budget);
|
|
10884
|
+
return Promise.resolve(result).then((then2) => isSandboxClosure(then2) ? then2 : void 0);
|
|
10885
|
+
}
|
|
10886
|
+
const then = descriptor?.value;
|
|
10556
10887
|
return isSandboxClosure(then) ? then : void 0;
|
|
10557
10888
|
}
|
|
10558
10889
|
function budgetIfNeeded(value, budget) {
|
|
@@ -10843,6 +11174,13 @@ function ownEnumerableSandboxEntries(value, excludedKeys) {
|
|
|
10843
11174
|
else entries = Object.entries(Object(value));
|
|
10844
11175
|
return excludedKeys === void 0 ? entries : entries.filter(([key]) => !excludedKeys.has(key));
|
|
10845
11176
|
}
|
|
11177
|
+
function ownEnumerableSandboxKeys(value) {
|
|
11178
|
+
if (isGuestHostObject(value)) return getHostObjectKeys(value);
|
|
11179
|
+
if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
|
|
11180
|
+
if (isGuestClosure(value)) return Object.keys(value.properties ?? {});
|
|
11181
|
+
if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
|
|
11182
|
+
return Object.keys(Object(value));
|
|
11183
|
+
}
|
|
10846
11184
|
function createSandboxPromise(promise, metadata = {}) {
|
|
10847
11185
|
const original = metadata.trackReplay === false ? promise : promiseReplayContext.getStore()?.track(promise) ?? promise;
|
|
10848
11186
|
const sandboxPromise = {
|
|
@@ -10997,6 +11335,7 @@ function measureSandboxData(values, options = {}) {
|
|
|
10997
11335
|
for (const [key, descriptor] of boxedDataProperties(value)) {
|
|
10998
11336
|
usage += key.length + 1;
|
|
10999
11337
|
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
11338
|
+
else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
|
|
11000
11339
|
}
|
|
11001
11340
|
return;
|
|
11002
11341
|
}
|
|
@@ -11029,6 +11368,7 @@ function measureSandboxData(values, options = {}) {
|
|
|
11029
11368
|
if (key === "length") continue;
|
|
11030
11369
|
usage += key.length + 1;
|
|
11031
11370
|
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
11371
|
+
else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
|
|
11032
11372
|
}
|
|
11033
11373
|
return;
|
|
11034
11374
|
}
|
|
@@ -11067,6 +11407,7 @@ function measureSandboxData(values, options = {}) {
|
|
|
11067
11407
|
if (key === "prototype" || key === "name" || key === "length") continue;
|
|
11068
11408
|
usage += key.length + 1;
|
|
11069
11409
|
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
11410
|
+
else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
|
|
11070
11411
|
}
|
|
11071
11412
|
} else visit(value.properties, depth + 1);
|
|
11072
11413
|
}
|
|
@@ -11110,7 +11451,8 @@ function measureSandboxData(values, options = {}) {
|
|
|
11110
11451
|
const descriptor = descriptors[key];
|
|
11111
11452
|
if (!descriptor.enumerable && !hasManagedDescriptors(value)) continue;
|
|
11112
11453
|
usage += key.length;
|
|
11113
|
-
|
|
11454
|
+
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
11455
|
+
else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
|
|
11114
11456
|
}
|
|
11115
11457
|
};
|
|
11116
11458
|
for (const value of values) visit(value);
|
|
@@ -24466,24 +24808,32 @@ async function bindAssignmentPattern2(pattern, value, target, scope, context) {
|
|
|
24466
24808
|
async function bindArrayPattern2(pattern, value, target, scope, context) {
|
|
24467
24809
|
const iterator = isSandboxCollectionIterator(value) ? value : void 0;
|
|
24468
24810
|
const values = iterator === void 0 ? getArrayPatternValues(value) : void 0;
|
|
24811
|
+
let cursor = 0;
|
|
24812
|
+
let done = false;
|
|
24813
|
+
const next = async () => {
|
|
24814
|
+
if (iterator !== void 0) return nextCollectionIterator(iterator, context.budget);
|
|
24815
|
+
if (done || cursor >= values.length) {
|
|
24816
|
+
done = true;
|
|
24817
|
+
return { done: true, value: void 0 };
|
|
24818
|
+
}
|
|
24819
|
+
return { done: false, value: await context.getProperty(values, cursor++) };
|
|
24820
|
+
};
|
|
24469
24821
|
for (let index = 0; index < pattern.elements.length; index += 1) {
|
|
24470
24822
|
const element = pattern.elements[index];
|
|
24471
24823
|
if (element === null) {
|
|
24472
|
-
|
|
24824
|
+
await next();
|
|
24473
24825
|
continue;
|
|
24474
24826
|
}
|
|
24475
24827
|
let elementValue;
|
|
24476
|
-
if (
|
|
24477
|
-
elementValue = element.type === "RestElement" ? values.slice(index) : values[index];
|
|
24478
|
-
} else if (element.type === "RestElement") {
|
|
24828
|
+
if (element.type === "RestElement") {
|
|
24479
24829
|
const rest = [];
|
|
24480
|
-
for (let entry =
|
|
24830
|
+
for (let entry = await next(); !entry.done; entry = await next()) {
|
|
24481
24831
|
context.budget?.allocateArrayLength(rest.length + 1);
|
|
24482
24832
|
rest.push(entry.value);
|
|
24483
24833
|
}
|
|
24484
24834
|
elementValue = rest;
|
|
24485
24835
|
} else {
|
|
24486
|
-
elementValue =
|
|
24836
|
+
elementValue = (await next()).value;
|
|
24487
24837
|
}
|
|
24488
24838
|
const binding = await bindPattern2(element, elementValue, target, scope, context);
|
|
24489
24839
|
if (!binding.ok) {
|
|
@@ -24501,7 +24851,7 @@ async function bindObjectPattern2(pattern, value, target, scope, context) {
|
|
|
24501
24851
|
if (property.type === "RestElement") {
|
|
24502
24852
|
const binding2 = await bindPattern2(
|
|
24503
24853
|
property,
|
|
24504
|
-
copyObjectRestValue(value, excludedKeys),
|
|
24854
|
+
await copyObjectRestValue(value, excludedKeys, context),
|
|
24505
24855
|
target,
|
|
24506
24856
|
scope,
|
|
24507
24857
|
context
|
|
@@ -24518,7 +24868,7 @@ async function bindObjectPattern2(pattern, value, target, scope, context) {
|
|
|
24518
24868
|
excludedKeys.add(String(key.value));
|
|
24519
24869
|
const binding = await bindPattern2(
|
|
24520
24870
|
property.value,
|
|
24521
|
-
context.getProperty(value, key.value),
|
|
24871
|
+
await context.getProperty(value, key.value),
|
|
24522
24872
|
target,
|
|
24523
24873
|
scope,
|
|
24524
24874
|
context
|
|
@@ -24544,7 +24894,7 @@ async function bindMemberExpression(pattern, value, scope, context) {
|
|
|
24544
24894
|
if (!isIndexableValue(object.value)) {
|
|
24545
24895
|
throw new TypeError("Assignment expressions require a sandbox object property.");
|
|
24546
24896
|
}
|
|
24547
|
-
context.setProperty(object.value, await context.toPropertyKey(property.value), value);
|
|
24897
|
+
await context.setProperty(object.value, await context.toPropertyKey(property.value), value);
|
|
24548
24898
|
return { ok: true };
|
|
24549
24899
|
}
|
|
24550
24900
|
async function evaluatePatternKey(property, context) {
|
|
@@ -24595,12 +24945,18 @@ function describeRuntimeValue(value) {
|
|
|
24595
24945
|
if (typeof value === "object") return value.constructor?.name ?? "Object";
|
|
24596
24946
|
return typeof value;
|
|
24597
24947
|
}
|
|
24598
|
-
function copyObjectRestValue(value, excludedKeys) {
|
|
24948
|
+
async function copyObjectRestValue(value, excludedKeys, context) {
|
|
24599
24949
|
const rest = /* @__PURE__ */ Object.create(null);
|
|
24600
|
-
|
|
24601
|
-
|
|
24950
|
+
const release = context.budget === void 0 ? () => void 0 : retainValues(context.budget, () => [value, rest]);
|
|
24951
|
+
try {
|
|
24952
|
+
for (const key of ownEnumerableSandboxKeys(value)) {
|
|
24953
|
+
if (excludedKeys.has(key) || !hasOwnSandboxProperty(value, key, true)) continue;
|
|
24954
|
+
defineProperty(rest, key, await context.getProperty(value, key));
|
|
24955
|
+
}
|
|
24956
|
+
return rest;
|
|
24957
|
+
} finally {
|
|
24958
|
+
release();
|
|
24602
24959
|
}
|
|
24603
|
-
return rest;
|
|
24604
24960
|
}
|
|
24605
24961
|
function isIndexableValue(value) {
|
|
24606
24962
|
return typeof value === "object" && value !== null;
|
|
@@ -24734,144 +25090,6 @@ function getDatePrototype(value, budget, owner) {
|
|
|
24734
25090
|
return prototype === value ? null : prototype ?? null;
|
|
24735
25091
|
}
|
|
24736
25092
|
|
|
24737
|
-
// packages/safe-js/src/interp/globals/object.ts
|
|
24738
|
-
function createObjectGlobal(methods, budget) {
|
|
24739
|
-
const construct = ([value]) => {
|
|
24740
|
-
if (value === null || value === void 0) {
|
|
24741
|
-
budget.chargeDataUsage(1);
|
|
24742
|
-
return /* @__PURE__ */ Object.create(null);
|
|
24743
|
-
}
|
|
24744
|
-
if (typeof value !== "object") {
|
|
24745
|
-
const box = createSandboxBox(value);
|
|
24746
|
-
budget.chargeDataUsage(measureSandboxData([box]));
|
|
24747
|
-
return box;
|
|
24748
|
-
}
|
|
24749
|
-
return value;
|
|
24750
|
-
};
|
|
24751
|
-
const constructor = createSandboxClosure({
|
|
24752
|
-
guest: true,
|
|
24753
|
-
sandbox: true,
|
|
24754
|
-
name: "Object",
|
|
24755
|
-
length: 1,
|
|
24756
|
-
call: construct,
|
|
24757
|
-
construct: (args, context) => {
|
|
24758
|
-
if (context?.newTarget === void 0 || context.newTarget === constructor) return construct(args);
|
|
24759
|
-
const value = construct([]);
|
|
24760
|
-
const prototype2 = context.getProperty(context.newTarget, "prototype");
|
|
24761
|
-
if (typeof prototype2 === "object" && prototype2 !== null) setSandboxPrototype(value, prototype2, budget);
|
|
24762
|
-
return value;
|
|
24763
|
-
}
|
|
24764
|
-
});
|
|
24765
|
-
const properties = materializeFunctionProperties(constructor);
|
|
24766
|
-
const prototype = properties.prototype;
|
|
24767
|
-
Object.defineProperty(properties, "prototype", { writable: false });
|
|
24768
|
-
for (const [name, method] of Object.entries(methods)) {
|
|
24769
|
-
Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
|
|
24770
|
-
}
|
|
24771
|
-
const prototypeMethods = {
|
|
24772
|
-
toString: createSandboxClosure({
|
|
24773
|
-
sandbox: true,
|
|
24774
|
-
name: "toString",
|
|
24775
|
-
length: 0,
|
|
24776
|
-
call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
|
|
24777
|
-
}),
|
|
24778
|
-
valueOf: createSandboxClosure({
|
|
24779
|
-
sandbox: true,
|
|
24780
|
-
name: "valueOf",
|
|
24781
|
-
length: 0,
|
|
24782
|
-
call: (_args, context) => {
|
|
24783
|
-
const value = requireReceiver(context?.thisValue);
|
|
24784
|
-
return construct([value]);
|
|
24785
|
-
}
|
|
24786
|
-
}),
|
|
24787
|
-
hasOwnProperty: createSandboxClosure({
|
|
24788
|
-
sandbox: true,
|
|
24789
|
-
name: "hasOwnProperty",
|
|
24790
|
-
length: 1,
|
|
24791
|
-
call: async ([key], context) => hasOwnSandboxProperty(
|
|
24792
|
-
requireReceiver(context?.thisValue),
|
|
24793
|
-
await sandboxString(key, budget, context),
|
|
24794
|
-
false
|
|
24795
|
-
)
|
|
24796
|
-
}),
|
|
24797
|
-
propertyIsEnumerable: createSandboxClosure({
|
|
24798
|
-
sandbox: true,
|
|
24799
|
-
name: "propertyIsEnumerable",
|
|
24800
|
-
length: 1,
|
|
24801
|
-
call: async ([key], context) => hasOwnSandboxProperty(
|
|
24802
|
-
requireReceiver(context?.thisValue),
|
|
24803
|
-
await sandboxString(key, budget, context),
|
|
24804
|
-
true
|
|
24805
|
-
)
|
|
24806
|
-
}),
|
|
24807
|
-
isPrototypeOf: createSandboxClosure({
|
|
24808
|
-
sandbox: true,
|
|
24809
|
-
name: "isPrototypeOf",
|
|
24810
|
-
length: 1,
|
|
24811
|
-
call: ([value], context) => {
|
|
24812
|
-
if (typeof value !== "object" || value === null) return false;
|
|
24813
|
-
const receiver = requireReceiver(context?.thisValue);
|
|
24814
|
-
let depth = 0;
|
|
24815
|
-
for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
|
|
24816
|
-
budget.visitNode();
|
|
24817
|
-
assertSandboxDataDepth(depth++);
|
|
24818
|
-
if (current === receiver) return true;
|
|
24819
|
-
}
|
|
24820
|
-
return false;
|
|
24821
|
-
}
|
|
24822
|
-
})
|
|
24823
|
-
};
|
|
24824
|
-
for (const [name, method] of Object.entries(prototypeMethods)) {
|
|
24825
|
-
Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
|
|
24826
|
-
}
|
|
24827
|
-
markDescriptorObject(prototype);
|
|
24828
|
-
installObjectPrototype(budget, prototype, constructor);
|
|
24829
|
-
return constructor;
|
|
24830
|
-
}
|
|
24831
|
-
function requireReceiver(value) {
|
|
24832
|
-
if (value === null || value === void 0)
|
|
24833
|
-
throw new TypeError("Object method requires a non-null receiver.");
|
|
24834
|
-
return value;
|
|
24835
|
-
}
|
|
24836
|
-
function hasOwnSandboxProperty(value, key, enumerable) {
|
|
24837
|
-
requireReceiver(value);
|
|
24838
|
-
if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
|
|
24839
|
-
let properties;
|
|
24840
|
-
if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
|
|
24841
|
-
else if (isSandboxClosure(value)) {
|
|
24842
|
-
if (key === "length" || key === "name") return !enumerable;
|
|
24843
|
-
properties = value.properties ?? /* @__PURE__ */ Object.create(null);
|
|
24844
|
-
} else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
|
|
24845
|
-
return false;
|
|
24846
|
-
else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
|
|
24847
|
-
else properties = Object(value);
|
|
24848
|
-
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
24849
|
-
return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
|
|
24850
|
-
}
|
|
24851
|
-
function typeTag(value) {
|
|
24852
|
-
if (isSandboxBox(value)) value = boxedValue(value);
|
|
24853
|
-
if (value === void 0) return "Undefined";
|
|
24854
|
-
if (value === null) return "Null";
|
|
24855
|
-
if (typeof value === "string") return "String";
|
|
24856
|
-
if (typeof value === "number") return "Number";
|
|
24857
|
-
if (typeof value === "boolean") return "Boolean";
|
|
24858
|
-
if (isSandboxClosure(value)) {
|
|
24859
|
-
while (value.boundTarget !== void 0) value = value.boundTarget;
|
|
24860
|
-
return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
|
|
24861
|
-
}
|
|
24862
|
-
if (Array.isArray(value)) return "Array";
|
|
24863
|
-
if (isSandboxDate(value)) return "Date";
|
|
24864
|
-
if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
|
|
24865
|
-
if (isSandboxRegex(value)) return "RegExp";
|
|
24866
|
-
if (isSandboxMap(value)) return "Map";
|
|
24867
|
-
if (isSandboxSet(value)) return "Set";
|
|
24868
|
-
if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "Map Iterator" : "Set Iterator";
|
|
24869
|
-
if (isSandboxPromise(value)) return "Promise";
|
|
24870
|
-
if (isSandboxGenerator(value)) return "Generator";
|
|
24871
|
-
if (isFloat32Array(value)) return "Float32Array";
|
|
24872
|
-
return "Object";
|
|
24873
|
-
}
|
|
24874
|
-
|
|
24875
25093
|
// packages/safe-js/src/interp/globals/numeric-parsers.ts
|
|
24876
25094
|
function createNumericParsers(budget) {
|
|
24877
25095
|
return {
|
|
@@ -25477,12 +25695,17 @@ function createPrimitiveConstructor(options, budget) {
|
|
|
25477
25695
|
const prototype = createSandboxBox(initial);
|
|
25478
25696
|
const allocate = (value, context) => {
|
|
25479
25697
|
const box = createSandboxBox(value);
|
|
25698
|
+
const finish = (prototype2) => {
|
|
25699
|
+
if (typeof prototype2 === "object" && prototype2 !== null)
|
|
25700
|
+
setSandboxPrototype(box, prototype2, budget);
|
|
25701
|
+
budget.chargeDataUsage(measureSandboxData([box]));
|
|
25702
|
+
return box;
|
|
25703
|
+
};
|
|
25480
25704
|
if (context?.newTarget !== void 0 && context.newTarget !== constructor) {
|
|
25481
25705
|
const prototype2 = context.getProperty(context.newTarget, "prototype");
|
|
25482
|
-
|
|
25706
|
+
return prototype2 instanceof Promise ? prototype2.then(finish) : finish(prototype2);
|
|
25483
25707
|
}
|
|
25484
|
-
|
|
25485
|
-
return box;
|
|
25708
|
+
return finish(void 0);
|
|
25486
25709
|
};
|
|
25487
25710
|
const constructor = createSandboxClosure({
|
|
25488
25711
|
guest: true,
|
|
@@ -25543,147 +25766,185 @@ function createPrimitiveConstructor(options, budget) {
|
|
|
25543
25766
|
// packages/safe-js/src/interp/globals/object-array.ts
|
|
25544
25767
|
function createObjectArrayGlobals(options) {
|
|
25545
25768
|
return {
|
|
25546
|
-
Object: createObjectGlobal(
|
|
25547
|
-
|
|
25548
|
-
|
|
25549
|
-
|
|
25550
|
-
|
|
25551
|
-
|
|
25552
|
-
|
|
25553
|
-
|
|
25554
|
-
|
|
25555
|
-
|
|
25556
|
-
|
|
25557
|
-
|
|
25558
|
-
|
|
25559
|
-
|
|
25560
|
-
|
|
25561
|
-
|
|
25562
|
-
|
|
25563
|
-
|
|
25564
|
-
|
|
25565
|
-
|
|
25566
|
-
|
|
25567
|
-
|
|
25568
|
-
|
|
25569
|
-
|
|
25570
|
-
|
|
25571
|
-
|
|
25572
|
-
|
|
25573
|
-
|
|
25574
|
-
|
|
25575
|
-
|
|
25576
|
-
|
|
25577
|
-
|
|
25578
|
-
|
|
25579
|
-
|
|
25580
|
-
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
|
|
25584
|
-
|
|
25585
|
-
|
|
25586
|
-
|
|
25587
|
-
|
|
25588
|
-
|
|
25589
|
-
|
|
25590
|
-
|
|
25591
|
-
name: "defineProperty"
|
|
25592
|
-
}),
|
|
25593
|
-
defineProperties: createSandboxClosure({
|
|
25594
|
-
sandbox: true,
|
|
25595
|
-
call: ([value, descriptors]) => {
|
|
25596
|
-
const properties = ownEnumerableSandboxEntries(descriptors).map(([key, descriptor]) => [key, dataDescriptor(descriptor)]);
|
|
25597
|
-
for (const [key, descriptor] of properties) {
|
|
25598
|
-
defineDataProperty(value, key, descriptor, options.budget);
|
|
25599
|
-
}
|
|
25600
|
-
return value;
|
|
25601
|
-
},
|
|
25602
|
-
name: "defineProperties"
|
|
25603
|
-
}),
|
|
25604
|
-
getPrototypeOf: createSandboxClosure({
|
|
25605
|
-
sandbox: true,
|
|
25606
|
-
call: ([value]) => {
|
|
25607
|
-
if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
|
|
25608
|
-
if (value !== null && value !== void 0 && typeof value !== "object") value = createSandboxBox(value);
|
|
25609
|
-
objectProperties(value);
|
|
25610
|
-
return getSandboxPrototype(value, options.budget);
|
|
25611
|
-
},
|
|
25612
|
-
name: "getPrototypeOf"
|
|
25613
|
-
}),
|
|
25614
|
-
setPrototypeOf: createSandboxClosure({
|
|
25615
|
-
sandbox: true,
|
|
25616
|
-
call: ([value, prototype]) => {
|
|
25617
|
-
objectProperties(value, true);
|
|
25618
|
-
if (prototype !== null) objectProperties(prototype);
|
|
25619
|
-
setSandboxPrototype(value, prototype, options.budget);
|
|
25620
|
-
return value;
|
|
25621
|
-
},
|
|
25622
|
-
name: "setPrototypeOf"
|
|
25623
|
-
}),
|
|
25624
|
-
create: createSandboxClosure({
|
|
25625
|
-
sandbox: true,
|
|
25626
|
-
call: ([prototype, descriptors]) => {
|
|
25627
|
-
if (prototype !== null) objectProperties(prototype);
|
|
25628
|
-
const value = /* @__PURE__ */ Object.create(null);
|
|
25629
|
-
setSandboxPrototype(value, prototype, options.budget);
|
|
25630
|
-
if (descriptors !== void 0) {
|
|
25631
|
-
const properties = ownEnumerableSandboxEntries(descriptors).map(([key, descriptor]) => [key, dataDescriptor(descriptor)]);
|
|
25632
|
-
for (const [key, descriptor] of properties) {
|
|
25633
|
-
defineDataProperty(value, key, descriptor, options.budget);
|
|
25634
|
-
}
|
|
25635
|
-
}
|
|
25636
|
-
return allocateProducedSandboxValue(value, options.budget);
|
|
25637
|
-
},
|
|
25638
|
-
name: "create"
|
|
25639
|
-
}),
|
|
25640
|
-
is: createSandboxClosure({
|
|
25641
|
-
sandbox: true,
|
|
25642
|
-
call: ([left, right]) => Reflect.apply(Object.is, Object, [left, right]),
|
|
25643
|
-
name: "is"
|
|
25644
|
-
}),
|
|
25645
|
-
fromEntries: createSandboxClosure({
|
|
25646
|
-
sandbox: true,
|
|
25647
|
-
call: ([value], context) => {
|
|
25648
|
-
const iterator = getSandboxIterator(value, options.budget, context);
|
|
25649
|
-
if (iterator === void 0) {
|
|
25650
|
-
throw new TypeError("Object.fromEntries requires an iterable.");
|
|
25651
|
-
}
|
|
25652
|
-
if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
|
|
25769
|
+
Object: createObjectGlobal(
|
|
25770
|
+
{
|
|
25771
|
+
keys: createSandboxClosure({
|
|
25772
|
+
sandbox: true,
|
|
25773
|
+
call: ([value]) => budgetSandboxValue2(ownEnumerableSandboxKeys(value), options.budget),
|
|
25774
|
+
name: "keys"
|
|
25775
|
+
}),
|
|
25776
|
+
values: createSandboxClosure({
|
|
25777
|
+
sandbox: true,
|
|
25778
|
+
call: ([value], context) => context === void 0 ? allocateProducedSandboxValue(
|
|
25779
|
+
ownEnumerableSandboxEntries(value).map(([, entry]) => entry),
|
|
25780
|
+
options.budget
|
|
25781
|
+
) : getOwnEnumerableEntries(value, options.budget, context).then(
|
|
25782
|
+
(entries) => allocateProducedSandboxValue(
|
|
25783
|
+
entries.map(([, entry]) => entry),
|
|
25784
|
+
options.budget
|
|
25785
|
+
)
|
|
25786
|
+
),
|
|
25787
|
+
name: "values"
|
|
25788
|
+
}),
|
|
25789
|
+
entries: createSandboxClosure({
|
|
25790
|
+
sandbox: true,
|
|
25791
|
+
call: ([value], context) => context === void 0 ? allocateProducedSandboxValue(ownEnumerableSandboxEntries(value), options.budget) : getOwnEnumerableEntries(value, options.budget, context).then(
|
|
25792
|
+
(entries) => allocateProducedSandboxValue(entries, options.budget)
|
|
25793
|
+
),
|
|
25794
|
+
name: "entries"
|
|
25795
|
+
}),
|
|
25796
|
+
hasOwn: createSandboxClosure({
|
|
25797
|
+
sandbox: true,
|
|
25798
|
+
call: ([value, key], context) => {
|
|
25799
|
+
if (value === null || value === void 0)
|
|
25800
|
+
throw new TypeError("Cannot convert undefined or null to object.");
|
|
25801
|
+
const name = sandboxString(key, options.budget, context);
|
|
25802
|
+
return typeof name === "string" ? hasOwnSandboxProperty(value, name, false) : name.then((property) => hasOwnSandboxProperty(value, property, false));
|
|
25803
|
+
},
|
|
25804
|
+
name: "hasOwn"
|
|
25805
|
+
}),
|
|
25806
|
+
getOwnPropertyDescriptor: createSandboxClosure({
|
|
25807
|
+
sandbox: true,
|
|
25808
|
+
call: async ([value, key], context) => {
|
|
25809
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
25810
|
+
objectProperties(value),
|
|
25811
|
+
await sandboxString(key, options.budget, context)
|
|
25812
|
+
);
|
|
25813
|
+
if (descriptor === void 0) return void 0;
|
|
25653
25814
|
return allocateProducedSandboxValue(
|
|
25654
|
-
|
|
25655
|
-
Reflect.apply(Object.fromEntries, Object, [{ [Symbol.iterator]: () => iterator }]),
|
|
25656
|
-
null
|
|
25657
|
-
),
|
|
25815
|
+
exposePropertyDescriptor(descriptor),
|
|
25658
25816
|
options.budget
|
|
25659
25817
|
);
|
|
25660
|
-
}
|
|
25661
|
-
|
|
25662
|
-
},
|
|
25663
|
-
|
|
25664
|
-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
25669
|
-
|
|
25670
|
-
|
|
25671
|
-
|
|
25672
|
-
|
|
25673
|
-
|
|
25674
|
-
|
|
25675
|
-
|
|
25676
|
-
|
|
25677
|
-
|
|
25678
|
-
|
|
25679
|
-
|
|
25680
|
-
|
|
25681
|
-
|
|
25682
|
-
|
|
25683
|
-
|
|
25684
|
-
|
|
25685
|
-
|
|
25686
|
-
|
|
25818
|
+
},
|
|
25819
|
+
name: "getOwnPropertyDescriptor"
|
|
25820
|
+
}),
|
|
25821
|
+
getOwnPropertyDescriptors: createSandboxClosure({
|
|
25822
|
+
sandbox: true,
|
|
25823
|
+
call: ([value]) => {
|
|
25824
|
+
const descriptors = /* @__PURE__ */ Object.create(null);
|
|
25825
|
+
for (const [key, descriptor] of Object.entries(
|
|
25826
|
+
Object.getOwnPropertyDescriptors(objectProperties(value))
|
|
25827
|
+
))
|
|
25828
|
+
defineOwnDataProperty(descriptors, key, exposePropertyDescriptor(descriptor));
|
|
25829
|
+
return allocateProducedSandboxValue(descriptors, options.budget);
|
|
25830
|
+
},
|
|
25831
|
+
name: "getOwnPropertyDescriptors"
|
|
25832
|
+
}),
|
|
25833
|
+
getOwnPropertyNames: createSandboxClosure({
|
|
25834
|
+
sandbox: true,
|
|
25835
|
+
call: ([value]) => budgetSandboxValue2(Object.getOwnPropertyNames(objectProperties(value)), options.budget),
|
|
25836
|
+
name: "getOwnPropertyNames"
|
|
25837
|
+
}),
|
|
25838
|
+
defineProperty: createSandboxClosure({
|
|
25839
|
+
sandbox: true,
|
|
25840
|
+
call: async ([value, key, descriptor], context) => {
|
|
25841
|
+
objectProperties(value, true);
|
|
25842
|
+
const property = await sandboxString(key, options.budget, context);
|
|
25843
|
+
defineDataProperty(
|
|
25844
|
+
value,
|
|
25845
|
+
property,
|
|
25846
|
+
await propertyDescriptor(descriptor, options.budget, context),
|
|
25847
|
+
options.budget
|
|
25848
|
+
);
|
|
25849
|
+
return value;
|
|
25850
|
+
},
|
|
25851
|
+
name: "defineProperty"
|
|
25852
|
+
}),
|
|
25853
|
+
defineProperties: createSandboxClosure({
|
|
25854
|
+
sandbox: true,
|
|
25855
|
+
call: async ([value, descriptors], context) => {
|
|
25856
|
+
await definePropertiesFromObject(value, descriptors, options.budget, context);
|
|
25857
|
+
return value;
|
|
25858
|
+
},
|
|
25859
|
+
name: "defineProperties"
|
|
25860
|
+
}),
|
|
25861
|
+
getPrototypeOf: createSandboxClosure({
|
|
25862
|
+
sandbox: true,
|
|
25863
|
+
call: ([value]) => {
|
|
25864
|
+
if (isSandboxDate(value))
|
|
25865
|
+
return getDatePrototype(value, options.budget, options.compileOwner);
|
|
25866
|
+
if (value !== null && value !== void 0 && typeof value !== "object")
|
|
25867
|
+
value = createSandboxBox(value);
|
|
25868
|
+
objectProperties(value);
|
|
25869
|
+
return getSandboxPrototype(value, options.budget);
|
|
25870
|
+
},
|
|
25871
|
+
name: "getPrototypeOf"
|
|
25872
|
+
}),
|
|
25873
|
+
setPrototypeOf: createSandboxClosure({
|
|
25874
|
+
sandbox: true,
|
|
25875
|
+
call: ([value, prototype]) => {
|
|
25876
|
+
objectProperties(value, true);
|
|
25877
|
+
if (prototype !== null) objectProperties(prototype);
|
|
25878
|
+
setSandboxPrototype(value, prototype, options.budget);
|
|
25879
|
+
return value;
|
|
25880
|
+
},
|
|
25881
|
+
name: "setPrototypeOf"
|
|
25882
|
+
}),
|
|
25883
|
+
create: createSandboxClosure({
|
|
25884
|
+
sandbox: true,
|
|
25885
|
+
call: async ([prototype, descriptors], context) => {
|
|
25886
|
+
if (prototype !== null) objectProperties(prototype);
|
|
25887
|
+
const value = /* @__PURE__ */ Object.create(null);
|
|
25888
|
+
setSandboxPrototype(value, prototype, options.budget);
|
|
25889
|
+
if (descriptors !== void 0) {
|
|
25890
|
+
await definePropertiesFromObject(value, descriptors, options.budget, context);
|
|
25891
|
+
}
|
|
25892
|
+
return allocateProducedSandboxValue(value, options.budget);
|
|
25893
|
+
},
|
|
25894
|
+
name: "create"
|
|
25895
|
+
}),
|
|
25896
|
+
is: createSandboxClosure({
|
|
25897
|
+
sandbox: true,
|
|
25898
|
+
call: ([left, right]) => Reflect.apply(Object.is, Object, [left, right]),
|
|
25899
|
+
name: "is"
|
|
25900
|
+
}),
|
|
25901
|
+
fromEntries: createSandboxClosure({
|
|
25902
|
+
sandbox: true,
|
|
25903
|
+
call: ([value], context) => {
|
|
25904
|
+
const iterator = getSandboxIterator(value, options.budget, context);
|
|
25905
|
+
if (iterator === void 0) {
|
|
25906
|
+
throw new TypeError("Object.fromEntries requires an iterable.");
|
|
25907
|
+
}
|
|
25908
|
+
if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
|
|
25909
|
+
return allocateProducedSandboxValue(
|
|
25910
|
+
Object.setPrototypeOf(
|
|
25911
|
+
Reflect.apply(Object.fromEntries, Object, [
|
|
25912
|
+
{ [Symbol.iterator]: () => iterator }
|
|
25913
|
+
]),
|
|
25914
|
+
null
|
|
25915
|
+
),
|
|
25916
|
+
options.budget
|
|
25917
|
+
);
|
|
25918
|
+
}
|
|
25919
|
+
return objectFromSandboxEntries(value, iterator, options.budget, context);
|
|
25920
|
+
},
|
|
25921
|
+
name: "fromEntries"
|
|
25922
|
+
}),
|
|
25923
|
+
freeze: createSandboxClosure({
|
|
25924
|
+
sandbox: true,
|
|
25925
|
+
call: ([value]) => {
|
|
25926
|
+
if (isGuestHostObject(value))
|
|
25927
|
+
throw new TypeError("Live host objects cannot be frozen.");
|
|
25928
|
+
if (typeof value === "object" && value !== null) {
|
|
25929
|
+
Object.freeze(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
|
|
25930
|
+
}
|
|
25931
|
+
return value;
|
|
25932
|
+
},
|
|
25933
|
+
name: "freeze"
|
|
25934
|
+
}),
|
|
25935
|
+
isFrozen: createSandboxClosure({
|
|
25936
|
+
sandbox: true,
|
|
25937
|
+
call: ([value]) => Object.isFrozen(isGuestClosure(value) ? materializeFunctionProperties(value) : value),
|
|
25938
|
+
name: "isFrozen"
|
|
25939
|
+
}),
|
|
25940
|
+
assign: createSandboxClosure({
|
|
25941
|
+
sandbox: true,
|
|
25942
|
+
call: ([target, ...sources], context) => assignSandboxValues(target, sources, options.budget, context),
|
|
25943
|
+
name: "assign"
|
|
25944
|
+
})
|
|
25945
|
+
},
|
|
25946
|
+
options.budget
|
|
25947
|
+
),
|
|
25687
25948
|
Array: createSandboxClosure({
|
|
25688
25949
|
sandbox: true,
|
|
25689
25950
|
call: (args) => createArrayFromConstructorArgs(args, options.budget),
|
|
@@ -25707,66 +25968,75 @@ function createObjectArrayGlobals(options) {
|
|
|
25707
25968
|
})
|
|
25708
25969
|
}
|
|
25709
25970
|
}),
|
|
25710
|
-
String: createPrimitiveConstructor(
|
|
25711
|
-
|
|
25712
|
-
|
|
25713
|
-
|
|
25714
|
-
|
|
25715
|
-
|
|
25716
|
-
|
|
25717
|
-
|
|
25718
|
-
|
|
25719
|
-
|
|
25720
|
-
|
|
25721
|
-
|
|
25722
|
-
|
|
25723
|
-
|
|
25724
|
-
|
|
25725
|
-
|
|
25726
|
-
|
|
25727
|
-
|
|
25728
|
-
|
|
25729
|
-
|
|
25730
|
-
|
|
25731
|
-
|
|
25732
|
-
|
|
25733
|
-
|
|
25734
|
-
|
|
25735
|
-
|
|
25736
|
-
|
|
25737
|
-
|
|
25738
|
-
|
|
25739
|
-
|
|
25740
|
-
|
|
25741
|
-
|
|
25742
|
-
|
|
25743
|
-
|
|
25744
|
-
|
|
25745
|
-
|
|
25746
|
-
|
|
25747
|
-
|
|
25748
|
-
|
|
25749
|
-
|
|
25750
|
-
|
|
25751
|
-
|
|
25752
|
-
|
|
25753
|
-
|
|
25754
|
-
|
|
25755
|
-
|
|
25756
|
-
|
|
25757
|
-
|
|
25758
|
-
|
|
25759
|
-
|
|
25760
|
-
|
|
25761
|
-
|
|
25762
|
-
|
|
25763
|
-
|
|
25764
|
-
|
|
25765
|
-
|
|
25766
|
-
|
|
25767
|
-
|
|
25768
|
-
|
|
25769
|
-
|
|
25971
|
+
String: createPrimitiveConstructor(
|
|
25972
|
+
{
|
|
25973
|
+
call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
|
|
25974
|
+
name: "String",
|
|
25975
|
+
properties: {
|
|
25976
|
+
raw: createSandboxClosure({
|
|
25977
|
+
sandbox: true,
|
|
25978
|
+
call: (args, context) => stringRaw(args, options.budget, context),
|
|
25979
|
+
name: "raw"
|
|
25980
|
+
}),
|
|
25981
|
+
fromCharCode: createSandboxClosure({
|
|
25982
|
+
sandbox: true,
|
|
25983
|
+
call: (args) => options.budget.allocateString(Reflect.apply(String.fromCharCode, String, [...args])),
|
|
25984
|
+
name: "fromCharCode"
|
|
25985
|
+
}),
|
|
25986
|
+
fromCodePoint: createSandboxClosure({
|
|
25987
|
+
sandbox: true,
|
|
25988
|
+
call: (args) => options.budget.allocateString(Reflect.apply(String.fromCodePoint, String, [...args])),
|
|
25989
|
+
name: "fromCodePoint"
|
|
25990
|
+
})
|
|
25991
|
+
}
|
|
25992
|
+
},
|
|
25993
|
+
options.budget
|
|
25994
|
+
),
|
|
25995
|
+
Number: createPrimitiveConstructor(
|
|
25996
|
+
{
|
|
25997
|
+
call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
|
|
25998
|
+
name: "Number",
|
|
25999
|
+
properties: {
|
|
26000
|
+
isFinite: createSandboxClosure({
|
|
26001
|
+
sandbox: true,
|
|
26002
|
+
call: ([value]) => typeof value === "number" && Number.isFinite(value),
|
|
26003
|
+
name: "isFinite"
|
|
26004
|
+
}),
|
|
26005
|
+
isNaN: createSandboxClosure({
|
|
26006
|
+
sandbox: true,
|
|
26007
|
+
call: ([value]) => typeof value === "number" && Number.isNaN(value),
|
|
26008
|
+
name: "isNaN"
|
|
26009
|
+
}),
|
|
26010
|
+
isInteger: createSandboxClosure({
|
|
26011
|
+
sandbox: true,
|
|
26012
|
+
call: ([value]) => typeof value === "number" && Number.isInteger(value),
|
|
26013
|
+
name: "isInteger"
|
|
26014
|
+
}),
|
|
26015
|
+
...createNumericParsers(options.budget),
|
|
26016
|
+
isSafeInteger: createSandboxClosure({
|
|
26017
|
+
sandbox: true,
|
|
26018
|
+
call: ([value]) => typeof value === "number" && Number.isSafeInteger(value),
|
|
26019
|
+
name: "isSafeInteger"
|
|
26020
|
+
}),
|
|
26021
|
+
MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER,
|
|
26022
|
+
MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER,
|
|
26023
|
+
EPSILON: Number.EPSILON,
|
|
26024
|
+
MAX_VALUE: Number.MAX_VALUE,
|
|
26025
|
+
MIN_VALUE: Number.MIN_VALUE,
|
|
26026
|
+
NaN: Number.NaN,
|
|
26027
|
+
NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
|
|
26028
|
+
POSITIVE_INFINITY: Number.POSITIVE_INFINITY
|
|
26029
|
+
}
|
|
26030
|
+
},
|
|
26031
|
+
options.budget
|
|
26032
|
+
),
|
|
26033
|
+
Boolean: createPrimitiveConstructor(
|
|
26034
|
+
{
|
|
26035
|
+
call: ([value]) => Boolean(value),
|
|
26036
|
+
name: "Boolean"
|
|
26037
|
+
},
|
|
26038
|
+
options.budget
|
|
26039
|
+
)
|
|
25770
26040
|
};
|
|
25771
26041
|
}
|
|
25772
26042
|
async function objectFromSandboxEntries(items, iterator, budget, context) {
|
|
@@ -25776,7 +26046,15 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
|
|
|
25776
26046
|
let value;
|
|
25777
26047
|
let failure;
|
|
25778
26048
|
const retained = {};
|
|
25779
|
-
budget.setRetainedValues(retained, () => [
|
|
26049
|
+
budget.setRetainedValues(retained, () => [
|
|
26050
|
+
items,
|
|
26051
|
+
iterator.retainedValue,
|
|
26052
|
+
object,
|
|
26053
|
+
entry,
|
|
26054
|
+
key,
|
|
26055
|
+
value,
|
|
26056
|
+
failure
|
|
26057
|
+
]);
|
|
25780
26058
|
const checkData = createDataCheckpoint(budget, context);
|
|
25781
26059
|
const closeOnThrow = async (error) => {
|
|
25782
26060
|
failure = isCapturedException(error) ? error.reason : error;
|
|
@@ -25805,8 +26083,8 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
|
|
|
25805
26083
|
if (typeof entry !== "object" || entry === null) {
|
|
25806
26084
|
throw new TypeError("Object.fromEntries requires entry objects.");
|
|
25807
26085
|
}
|
|
25808
|
-
key = context?.getProperty !== void 0 ? context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, budget);
|
|
25809
|
-
value = context?.getProperty !== void 0 ? context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, budget);
|
|
26086
|
+
key = context?.getProperty !== void 0 ? await context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, budget);
|
|
26087
|
+
value = context?.getProperty !== void 0 ? await context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, budget);
|
|
25810
26088
|
const property = await sandboxString(key, budget, context);
|
|
25811
26089
|
const growth = property.length + 1 + (budget.limits.dataSize === void 0 ? 0 : measureSandboxData([value]));
|
|
25812
26090
|
budget.visitNode();
|
|
@@ -25823,7 +26101,7 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
|
|
|
25823
26101
|
budget.setRetainedValues(retained, void 0);
|
|
25824
26102
|
}
|
|
25825
26103
|
}
|
|
25826
|
-
function assignSandboxValues(target, sources, budget) {
|
|
26104
|
+
function assignSandboxValues(target, sources, budget, context) {
|
|
25827
26105
|
if (target === null || target === void 0) {
|
|
25828
26106
|
throw new TypeError("Object.assign(target, ...sources) requires a non-null target.");
|
|
25829
26107
|
}
|
|
@@ -25834,50 +26112,120 @@ function assignSandboxValues(target, sources, budget) {
|
|
|
25834
26112
|
if (!isGuestClosure(target) && !isAssignableSandboxTarget(target)) {
|
|
25835
26113
|
throw new TypeError("Object.assign(target, ...sources) requires an object or array target.");
|
|
25836
26114
|
}
|
|
25837
|
-
|
|
25838
|
-
|
|
25839
|
-
continue;
|
|
25840
|
-
|
|
25841
|
-
|
|
25842
|
-
setSandboxProperty(target, key, value, budget);
|
|
26115
|
+
if (context === void 0) {
|
|
26116
|
+
for (const source of sources) {
|
|
26117
|
+
if (source === null || source === void 0) continue;
|
|
26118
|
+
for (const [key, value] of ownEnumerableSandboxEntries(source))
|
|
26119
|
+
setSandboxProperty(target, key, value, budget);
|
|
25843
26120
|
}
|
|
26121
|
+
return target;
|
|
25844
26122
|
}
|
|
25845
|
-
return
|
|
26123
|
+
return (async () => {
|
|
26124
|
+
const release = retainValues(budget, () => [target, ...sources]);
|
|
26125
|
+
try {
|
|
26126
|
+
for (const source of sources) {
|
|
26127
|
+
if (source === null || source === void 0) continue;
|
|
26128
|
+
for (const key of ownEnumerableSandboxKeys(source)) {
|
|
26129
|
+
if (!hasOwnSandboxProperty(source, key, true)) continue;
|
|
26130
|
+
const value = await (context.getProperty !== void 0 ? context.getProperty(source, key) : getSandboxDataProperty(source, key, budget));
|
|
26131
|
+
await setSandboxProperty(target, key, value, budget, true, context);
|
|
26132
|
+
}
|
|
26133
|
+
}
|
|
26134
|
+
return target;
|
|
26135
|
+
} finally {
|
|
26136
|
+
release();
|
|
26137
|
+
}
|
|
26138
|
+
})();
|
|
25846
26139
|
}
|
|
25847
26140
|
function objectProperties(value, mutable = false) {
|
|
25848
26141
|
if (isSandboxDate(value)) {
|
|
25849
26142
|
if (mutable) throw new TypeError("Date own properties and prototypes are not supported.");
|
|
25850
26143
|
return value;
|
|
25851
26144
|
}
|
|
25852
|
-
if (isGuestHostObject(value))
|
|
26145
|
+
if (isGuestHostObject(value))
|
|
26146
|
+
throw new TypeError("Live host object descriptors are not supported.");
|
|
25853
26147
|
if (isGuestClosure(value)) return materializeFunctionProperties(value);
|
|
25854
26148
|
if (isSandboxClosure(value)) {
|
|
25855
26149
|
if (mutable) throw new TypeError("Host function properties are read only.");
|
|
25856
26150
|
return value.properties ?? /* @__PURE__ */ Object.create(null);
|
|
25857
26151
|
}
|
|
25858
|
-
if (!isAssignableSandboxTarget(value))
|
|
26152
|
+
if (!isAssignableSandboxTarget(value))
|
|
26153
|
+
throw new TypeError("Expected a sandbox object or function.");
|
|
25859
26154
|
return value;
|
|
25860
26155
|
}
|
|
25861
|
-
function
|
|
25862
|
-
|
|
26156
|
+
function exposePropertyDescriptor(descriptor) {
|
|
26157
|
+
return "value" in descriptor ? descriptor : {
|
|
26158
|
+
get: accessorClosure(descriptor.get),
|
|
26159
|
+
set: accessorClosure(descriptor.set),
|
|
26160
|
+
enumerable: descriptor.enumerable,
|
|
26161
|
+
configurable: descriptor.configurable
|
|
26162
|
+
};
|
|
26163
|
+
}
|
|
26164
|
+
async function propertyDescriptor(input, budget, context) {
|
|
26165
|
+
objectProperties(input);
|
|
25863
26166
|
const descriptor = {};
|
|
25864
|
-
|
|
25865
|
-
|
|
25866
|
-
|
|
25867
|
-
|
|
25868
|
-
|
|
26167
|
+
const release = retainValues(budget, () => [
|
|
26168
|
+
input,
|
|
26169
|
+
descriptor.value,
|
|
26170
|
+
...retainedAccessorClosures(descriptor)
|
|
26171
|
+
]);
|
|
26172
|
+
try {
|
|
26173
|
+
for (const field of [
|
|
26174
|
+
"enumerable",
|
|
26175
|
+
"configurable",
|
|
26176
|
+
"value",
|
|
26177
|
+
"writable",
|
|
26178
|
+
"get",
|
|
26179
|
+
"set"
|
|
26180
|
+
]) {
|
|
26181
|
+
if (getSandboxPropertyDescriptor(input, field, budget) === void 0 && !hasOwnSandboxProperty(input, field, false))
|
|
26182
|
+
continue;
|
|
26183
|
+
const value = await (context?.getProperty !== void 0 ? context.getProperty(input, field) : getSandboxDataProperty(input, field, budget));
|
|
26184
|
+
if (field === "get" || field === "set") {
|
|
26185
|
+
if (value !== void 0 && !isSandboxClosure(value))
|
|
26186
|
+
throw new TypeError("Accessor must be a function or undefined.");
|
|
26187
|
+
descriptor[field] = value === void 0 ? void 0 : accessorAdapter(value, field);
|
|
26188
|
+
} else if (field === "value") {
|
|
26189
|
+
descriptor.value = value;
|
|
26190
|
+
} else {
|
|
26191
|
+
descriptor[field] = Boolean(value);
|
|
26192
|
+
}
|
|
25869
26193
|
}
|
|
25870
|
-
if (
|
|
25871
|
-
|
|
26194
|
+
if (("get" in descriptor || "set" in descriptor) && ("value" in descriptor || "writable" in descriptor))
|
|
26195
|
+
throw new TypeError("A property cannot be both a data property and an accessor.");
|
|
26196
|
+
return descriptor;
|
|
26197
|
+
} finally {
|
|
26198
|
+
release();
|
|
26199
|
+
}
|
|
26200
|
+
}
|
|
26201
|
+
async function definePropertiesFromObject(target, descriptors, budget, context) {
|
|
26202
|
+
objectProperties(target, true);
|
|
26203
|
+
const properties = [];
|
|
26204
|
+
const release = retainValues(budget, () => [
|
|
26205
|
+
target,
|
|
26206
|
+
descriptors,
|
|
26207
|
+
properties,
|
|
26208
|
+
...properties.flatMap(([, descriptor]) => retainedAccessorClosures(descriptor))
|
|
26209
|
+
]);
|
|
26210
|
+
try {
|
|
26211
|
+
for (const key of ownEnumerableSandboxKeys(descriptors)) {
|
|
26212
|
+
if (!hasOwnSandboxProperty(descriptors, key, true)) continue;
|
|
26213
|
+
const descriptor = await (context?.getProperty !== void 0 ? context.getProperty(descriptors, key) : getSandboxDataProperty(descriptors, key, budget));
|
|
26214
|
+
properties.push([key, await propertyDescriptor(descriptor, budget, context)]);
|
|
26215
|
+
}
|
|
26216
|
+
for (const [key, descriptor] of properties) defineDataProperty(target, key, descriptor, budget);
|
|
26217
|
+
} finally {
|
|
26218
|
+
release();
|
|
25872
26219
|
}
|
|
25873
|
-
return descriptor;
|
|
25874
26220
|
}
|
|
25875
26221
|
function defineDataProperty(target, key, descriptor, budget) {
|
|
25876
26222
|
budget.visitNode();
|
|
25877
|
-
if (isFloat32Array(target))
|
|
26223
|
+
if (isFloat32Array(target))
|
|
26224
|
+
throw new TypeError("Typed array property descriptors are not supported.");
|
|
25878
26225
|
const properties = objectProperties(target, true);
|
|
25879
26226
|
if (Array.isArray(properties)) {
|
|
25880
|
-
if (key === "length" && "value" in descriptor)
|
|
26227
|
+
if (key === "length" && "value" in descriptor)
|
|
26228
|
+
budget.allocateArrayLength(Number(descriptor.value));
|
|
25881
26229
|
else {
|
|
25882
26230
|
const index = Number(key);
|
|
25883
26231
|
if (Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === key) {
|
|
@@ -25906,7 +26254,15 @@ async function arrayFromSandboxValues(args, budget, context) {
|
|
|
25906
26254
|
let currentValue;
|
|
25907
26255
|
let failure;
|
|
25908
26256
|
const retained = {};
|
|
25909
|
-
budget.setRetainedValues(retained, () => [
|
|
26257
|
+
budget.setRetainedValues(retained, () => [
|
|
26258
|
+
items,
|
|
26259
|
+
iterator?.retainedValue,
|
|
26260
|
+
mapFn,
|
|
26261
|
+
constructor,
|
|
26262
|
+
result,
|
|
26263
|
+
currentValue,
|
|
26264
|
+
failure
|
|
26265
|
+
]);
|
|
25910
26266
|
const checkData = createDataCheckpoint(budget, context);
|
|
25911
26267
|
const closeOnThrow = async (error) => {
|
|
25912
26268
|
failure = isCapturedException(error) ? error.reason : error;
|
|
@@ -25920,30 +26276,46 @@ async function arrayFromSandboxValues(args, budget, context) {
|
|
|
25920
26276
|
try {
|
|
25921
26277
|
let length = 0;
|
|
25922
26278
|
if (iterator === void 0) {
|
|
25923
|
-
const number = await sandboxNumber(read("length"), budget, context);
|
|
26279
|
+
const number = await sandboxNumber(await read("length"), budget, context);
|
|
25924
26280
|
length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
|
|
25925
26281
|
}
|
|
25926
|
-
result = isSandboxClosure(constructor) && constructor.construct !== void 0 ? await invokeBuiltinClosure(
|
|
26282
|
+
result = isSandboxClosure(constructor) && constructor.construct !== void 0 ? await invokeBuiltinClosure(
|
|
26283
|
+
constructor,
|
|
26284
|
+
iterator === void 0 ? [length] : [],
|
|
26285
|
+
budget,
|
|
26286
|
+
context,
|
|
26287
|
+
void 0,
|
|
26288
|
+
true
|
|
26289
|
+
) : createArrayFromConstructorArgs([length], budget);
|
|
25927
26290
|
checkData(result, 0, true);
|
|
25928
26291
|
let index = 0;
|
|
25929
26292
|
while (iterator !== void 0 || index < length) {
|
|
25930
26293
|
try {
|
|
25931
26294
|
budget.visitNode();
|
|
25932
|
-
if (iterator !== void 0 && index >= Number.MAX_SAFE_INTEGER)
|
|
26295
|
+
if (iterator !== void 0 && index >= Number.MAX_SAFE_INTEGER)
|
|
26296
|
+
throw new TypeError("Array.from input is too long.");
|
|
25933
26297
|
} catch (error) {
|
|
25934
26298
|
await closeOnThrow(error);
|
|
25935
26299
|
}
|
|
25936
26300
|
if (iterator !== void 0) {
|
|
25937
26301
|
const next = await iterator.next();
|
|
25938
|
-
if (typeof next !== "object" || next === null)
|
|
26302
|
+
if (typeof next !== "object" || next === null)
|
|
26303
|
+
throw new TypeError("Iterator result must be an object.");
|
|
25939
26304
|
if (next.done) break;
|
|
25940
26305
|
currentValue = next.value;
|
|
25941
26306
|
} else {
|
|
25942
|
-
currentValue = read(index);
|
|
26307
|
+
currentValue = await read(index);
|
|
25943
26308
|
}
|
|
25944
26309
|
try {
|
|
25945
26310
|
if (Array.isArray(result)) budget.allocateArrayLength(index + 1);
|
|
25946
|
-
if (mapFn !== void 0)
|
|
26311
|
+
if (mapFn !== void 0)
|
|
26312
|
+
currentValue = await invokeBuiltinClosure(
|
|
26313
|
+
mapFn,
|
|
26314
|
+
[currentValue, index],
|
|
26315
|
+
budget,
|
|
26316
|
+
context,
|
|
26317
|
+
thisValue
|
|
26318
|
+
);
|
|
25947
26319
|
const key = String(index);
|
|
25948
26320
|
const growth = key.length + 1 + (Array.isArray(result) ? Math.max(0, index + 1 - result.length) : 0) + (budget.limits.dataSize === void 0 ? 0 : measureSandboxData([currentValue]));
|
|
25949
26321
|
budget.visitNode();
|
|
@@ -25981,19 +26353,60 @@ function createArrayFromConstructorArgs(args, budget) {
|
|
|
25981
26353
|
release();
|
|
25982
26354
|
}
|
|
25983
26355
|
}
|
|
25984
|
-
function
|
|
25985
|
-
|
|
25986
|
-
|
|
25987
|
-
|
|
25988
|
-
|
|
25989
|
-
|
|
26356
|
+
async function getOwnEnumerableEntries(value, budget, context) {
|
|
26357
|
+
const entries = [];
|
|
26358
|
+
const release = retainValues(budget, () => [value, entries]);
|
|
26359
|
+
try {
|
|
26360
|
+
for (const key of ownEnumerableSandboxKeys(value)) {
|
|
26361
|
+
if (!hasOwnSandboxProperty(value, key, true)) continue;
|
|
26362
|
+
entries.push([
|
|
26363
|
+
key,
|
|
26364
|
+
await (context?.getProperty !== void 0 ? context.getProperty(value, key) : getSandboxDataProperty(value, key, budget))
|
|
26365
|
+
]);
|
|
26366
|
+
}
|
|
26367
|
+
return entries;
|
|
26368
|
+
} finally {
|
|
26369
|
+
release();
|
|
26370
|
+
}
|
|
25990
26371
|
}
|
|
25991
26372
|
function budgetSandboxValue2(value, budget) {
|
|
25992
26373
|
const sandboxValue = deepCopyToSandbox(value);
|
|
25993
26374
|
return allocateProducedSandboxValue(sandboxValue, budget);
|
|
25994
26375
|
}
|
|
25995
|
-
function stringRaw(args, budget) {
|
|
26376
|
+
function stringRaw(args, budget, context) {
|
|
25996
26377
|
const [template, ...substitutions] = args;
|
|
26378
|
+
if (context?.getProperty !== void 0)
|
|
26379
|
+
return (async () => {
|
|
26380
|
+
if (template === null || template === void 0)
|
|
26381
|
+
throw new TypeError("String.raw requires a template object.");
|
|
26382
|
+
const raw2 = await context.getProperty(template, "raw");
|
|
26383
|
+
if (raw2 === null || raw2 === void 0)
|
|
26384
|
+
throw new TypeError("String.raw requires raw strings.");
|
|
26385
|
+
const number = await sandboxNumber(
|
|
26386
|
+
await context.getProperty(raw2, "length"),
|
|
26387
|
+
budget,
|
|
26388
|
+
context
|
|
26389
|
+
);
|
|
26390
|
+
const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
|
|
26391
|
+
let result2 = "";
|
|
26392
|
+
const retained = {};
|
|
26393
|
+
budget.setRetainedValues(retained, () => [raw2, result2]);
|
|
26394
|
+
try {
|
|
26395
|
+
for (let index = 0; index < length; index++) {
|
|
26396
|
+
budget.visitNode();
|
|
26397
|
+
result2 = budget.allocateString(
|
|
26398
|
+
result2 + await sandboxString(await context.getProperty(raw2, index), budget, context)
|
|
26399
|
+
);
|
|
26400
|
+
if (index + 1 < length && index < substitutions.length)
|
|
26401
|
+
result2 = budget.allocateString(
|
|
26402
|
+
result2 + await sandboxString(substitutions[index], budget, context)
|
|
26403
|
+
);
|
|
26404
|
+
}
|
|
26405
|
+
return result2;
|
|
26406
|
+
} finally {
|
|
26407
|
+
budget.setRetainedValues(retained, void 0);
|
|
26408
|
+
}
|
|
26409
|
+
})();
|
|
25997
26410
|
const raw = getTemplateRawParts(template);
|
|
25998
26411
|
let result = "";
|
|
25999
26412
|
for (let index = 0; index < raw.length; index += 1) {
|
|
@@ -26030,7 +26443,7 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
|
|
|
26030
26443
|
parent = result.value;
|
|
26031
26444
|
if (parent !== null && (!isSandboxClosure(parent) || parent.construct === void 0))
|
|
26032
26445
|
throw new TypeError("Class extends value is not a constructor or null.");
|
|
26033
|
-
prototypeParent = parent === null ? null : callContext.getProperty(parent, "prototype");
|
|
26446
|
+
prototypeParent = parent === null ? null : await callContext.getProperty(parent, "prototype");
|
|
26034
26447
|
if (prototypeParent !== null && typeof prototypeParent !== "object")
|
|
26035
26448
|
throw new TypeError("Class extends value has an invalid prototype.");
|
|
26036
26449
|
}
|
|
@@ -26070,7 +26483,7 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
|
|
|
26070
26483
|
};
|
|
26071
26484
|
if (!derived) {
|
|
26072
26485
|
thisValue = {};
|
|
26073
|
-
const targetPrototype = invocation.getProperty(newTarget, "prototype");
|
|
26486
|
+
const targetPrototype = await invocation.getProperty(newTarget, "prototype");
|
|
26074
26487
|
if (typeof targetPrototype === "object" && targetPrototype !== null)
|
|
26075
26488
|
setSandboxPrototype(thisValue, targetPrototype, context.budget);
|
|
26076
26489
|
}
|
|
@@ -26129,8 +26542,15 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
|
|
|
26129
26542
|
} else {
|
|
26130
26543
|
const home = element.static ? constructor : prototype;
|
|
26131
26544
|
const method = createInterpretedClosure(element.value, classContext, evaluateNode2, home);
|
|
26132
|
-
|
|
26133
|
-
Object.defineProperty(
|
|
26545
|
+
const accessor = element.kind === "get" || element.kind === "set" ? element.kind : void 0;
|
|
26546
|
+
Object.defineProperty(materializeFunctionProperties(method), "name", {
|
|
26547
|
+
value: accessor === void 0 ? key : `${accessor} ${key}`
|
|
26548
|
+
});
|
|
26549
|
+
Object.defineProperty(
|
|
26550
|
+
element.static ? properties : prototype,
|
|
26551
|
+
key,
|
|
26552
|
+
accessor === void 0 ? { value: method, configurable: true, writable: true, enumerable: false } : { [accessor]: accessorAdapter(method, accessor), configurable: true, enumerable: false }
|
|
26553
|
+
);
|
|
26134
26554
|
}
|
|
26135
26555
|
}
|
|
26136
26556
|
if (node.id !== void 0) scope.declare(node.id.name, "const", constructor);
|
|
@@ -26215,7 +26635,13 @@ function getArrayMember(value, property, options) {
|
|
|
26215
26635
|
return createSandboxClosure({
|
|
26216
26636
|
sandbox: true,
|
|
26217
26637
|
name: `Array#${property}`,
|
|
26218
|
-
call: (args, context) => callArrayMethod(
|
|
26638
|
+
call: (args, context) => callArrayMethod(
|
|
26639
|
+
context?.thisValue,
|
|
26640
|
+
property,
|
|
26641
|
+
args,
|
|
26642
|
+
{ ...options, context },
|
|
26643
|
+
context?.stack ?? []
|
|
26644
|
+
)
|
|
26219
26645
|
});
|
|
26220
26646
|
}
|
|
26221
26647
|
return void 0;
|
|
@@ -26231,7 +26657,8 @@ function isArrayMethodName(property) {
|
|
|
26231
26657
|
return typeof property === "string" && arrayMethodNames.has(property);
|
|
26232
26658
|
}
|
|
26233
26659
|
async function callArrayMethod(receiver, methodName, args, options, stack = []) {
|
|
26234
|
-
if (receiver === null || receiver === void 0)
|
|
26660
|
+
if (receiver === null || receiver === void 0)
|
|
26661
|
+
throw new TypeError("Array method requires a receiver.");
|
|
26235
26662
|
if (typeof receiver !== "object") {
|
|
26236
26663
|
receiver = createSandboxBox(receiver);
|
|
26237
26664
|
options.budget.chargeDataUsage(measureSandboxData([receiver]));
|
|
@@ -26268,38 +26695,44 @@ async function callArrayMethod(receiver, methodName, args, options, stack = [])
|
|
|
26268
26695
|
}
|
|
26269
26696
|
}
|
|
26270
26697
|
async function arrayLikeView(receiver, options) {
|
|
26271
|
-
const rawLength = options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
|
|
26698
|
+
const rawLength = options.context?.getProperty !== void 0 ? await options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
|
|
26272
26699
|
const number = await sandboxNumber(rawLength, options.budget, options.context);
|
|
26273
26700
|
const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
|
|
26274
|
-
const view = new Proxy(
|
|
26275
|
-
|
|
26276
|
-
|
|
26277
|
-
|
|
26278
|
-
|
|
26279
|
-
|
|
26280
|
-
|
|
26281
|
-
|
|
26282
|
-
|
|
26283
|
-
|
|
26284
|
-
|
|
26701
|
+
const view = new Proxy(
|
|
26702
|
+
/* @__PURE__ */ Object.create(null),
|
|
26703
|
+
{
|
|
26704
|
+
get: (_target, key) => {
|
|
26705
|
+
options.budget.visitNode();
|
|
26706
|
+
if (key === "length") return length;
|
|
26707
|
+
if (typeof key !== "string") return void 0;
|
|
26708
|
+
return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, key) : getSandboxDataProperty(receiver, key, options.budget);
|
|
26709
|
+
},
|
|
26710
|
+
has: (_target, key) => {
|
|
26711
|
+
options.budget.visitNode();
|
|
26712
|
+
if (typeof key === "string" && options.hasProperty !== void 0)
|
|
26713
|
+
return options.hasProperty(receiver, key);
|
|
26714
|
+
for (let current = receiver; current !== null; current = getSandboxPrototype(current, options.budget)) {
|
|
26715
|
+
options.budget.visitNode();
|
|
26716
|
+
if (Object.hasOwn(current, key)) return true;
|
|
26717
|
+
}
|
|
26718
|
+
return false;
|
|
26719
|
+
},
|
|
26720
|
+
set: (_target, key, entry) => {
|
|
26285
26721
|
options.budget.visitNode();
|
|
26286
|
-
if (
|
|
26722
|
+
if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
|
|
26723
|
+
if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
|
|
26724
|
+
else if (!Reflect.set(receiver, key, entry))
|
|
26725
|
+
throw new TypeError(`Cannot assign property '${key}'.`);
|
|
26726
|
+
return true;
|
|
26727
|
+
},
|
|
26728
|
+
deleteProperty: (_target, key) => {
|
|
26729
|
+
options.budget.visitNode();
|
|
26730
|
+
if (typeof key === "string" && options.deleteProperty !== void 0)
|
|
26731
|
+
return options.deleteProperty(receiver, key);
|
|
26732
|
+
return Reflect.deleteProperty(receiver, key);
|
|
26287
26733
|
}
|
|
26288
|
-
return false;
|
|
26289
|
-
},
|
|
26290
|
-
set: (_target, key, entry) => {
|
|
26291
|
-
options.budget.visitNode();
|
|
26292
|
-
if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
|
|
26293
|
-
if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
|
|
26294
|
-
else if (!Reflect.set(receiver, key, entry)) throw new TypeError(`Cannot assign property '${key}'.`);
|
|
26295
|
-
return true;
|
|
26296
|
-
},
|
|
26297
|
-
deleteProperty: (_target, key) => {
|
|
26298
|
-
options.budget.visitNode();
|
|
26299
|
-
if (typeof key === "string" && options.deleteProperty !== void 0) return options.deleteProperty(receiver, key);
|
|
26300
|
-
return Reflect.deleteProperty(receiver, key);
|
|
26301
26734
|
}
|
|
26302
|
-
|
|
26735
|
+
);
|
|
26303
26736
|
arrayLikeSources.set(view, receiver);
|
|
26304
26737
|
return view;
|
|
26305
26738
|
}
|
|
@@ -26403,166 +26836,371 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
|
|
|
26403
26836
|
);
|
|
26404
26837
|
case "flat":
|
|
26405
26838
|
return budgetProducedValue(
|
|
26406
|
-
flattenArray(
|
|
26839
|
+
await flattenArray(
|
|
26840
|
+
value,
|
|
26841
|
+
args[0] === void 0 ? 1 : toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context)),
|
|
26842
|
+
options
|
|
26843
|
+
),
|
|
26407
26844
|
options.budget
|
|
26408
26845
|
);
|
|
26409
26846
|
case "includes":
|
|
26410
|
-
return Reflect.apply(Array.prototype.includes, value, [...args]);
|
|
26411
26847
|
case "indexOf":
|
|
26412
|
-
|
|
26413
|
-
|
|
26414
|
-
|
|
26415
|
-
|
|
26416
|
-
|
|
26848
|
+
case "lastIndexOf": {
|
|
26849
|
+
const length = value.length;
|
|
26850
|
+
if (length === 0) return methodName === "includes" ? false : -1;
|
|
26851
|
+
const reverse = methodName === "lastIndexOf";
|
|
26852
|
+
const start = reverse && args.length < 2 ? length - 1 : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
|
|
26853
|
+
let index = reverse ? Math.min(start < 0 ? length + start : start, length - 1) : start < 0 ? Math.max(length + start, 0) : start;
|
|
26854
|
+
for (; index >= 0 && index < length; index += reverse ? -1 : 1) {
|
|
26855
|
+
options.budget.visitNode();
|
|
26856
|
+
if (methodName !== "includes" && !(index in value)) continue;
|
|
26857
|
+
const entry = await readArrayElement(value, index, options);
|
|
26858
|
+
if (entry === args[0] || methodName === "includes" && Number.isNaN(entry) && Number.isNaN(args[0]))
|
|
26859
|
+
return methodName === "includes" ? true : index;
|
|
26860
|
+
}
|
|
26861
|
+
return methodName === "includes" ? false : -1;
|
|
26862
|
+
}
|
|
26863
|
+
case "join": {
|
|
26864
|
+
const length = value.length;
|
|
26865
|
+
const separator = args[0] === void 0 ? "," : await sandboxString(args[0], options.budget, options.context);
|
|
26866
|
+
return joinSandboxArray(
|
|
26867
|
+
arrayLikeSources.get(value) ?? value,
|
|
26868
|
+
length,
|
|
26869
|
+
separator,
|
|
26870
|
+
options.budget,
|
|
26871
|
+
options.context
|
|
26872
|
+
);
|
|
26873
|
+
}
|
|
26417
26874
|
case "slice": {
|
|
26418
26875
|
const length = value.length;
|
|
26419
|
-
const start = toIntegerOrInfinity(
|
|
26876
|
+
const start = toIntegerOrInfinity(
|
|
26877
|
+
await sandboxNumber(args[0], options.budget, options.context)
|
|
26878
|
+
);
|
|
26420
26879
|
const end = args[1] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
|
|
26421
26880
|
const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
|
|
26422
26881
|
const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
|
|
26423
26882
|
const count = Math.max(final - first, 0);
|
|
26424
26883
|
options.budget.allocateArrayLength(count);
|
|
26425
26884
|
const result = new Array(count);
|
|
26426
|
-
|
|
26427
|
-
|
|
26428
|
-
|
|
26885
|
+
const release = retainValues(options.budget, () => [result]);
|
|
26886
|
+
try {
|
|
26887
|
+
for (let index = 0; index < count; index += 1) {
|
|
26888
|
+
options.budget.visitNode();
|
|
26889
|
+
if (first + index in value)
|
|
26890
|
+
result[index] = await readArrayElement(value, first + index, options);
|
|
26891
|
+
}
|
|
26892
|
+
return budgetProducedValue(result, options.budget);
|
|
26893
|
+
} finally {
|
|
26894
|
+
release();
|
|
26895
|
+
}
|
|
26896
|
+
}
|
|
26897
|
+
case "concat": {
|
|
26898
|
+
const result = [];
|
|
26899
|
+
const retained = {};
|
|
26900
|
+
options.budget.setRetainedValues(retained, () => [result]);
|
|
26901
|
+
try {
|
|
26902
|
+
for (const entry of [value, ...args]) {
|
|
26903
|
+
if (!Array.isArray(entry)) {
|
|
26904
|
+
options.budget.allocateArrayLength(result.length + 1);
|
|
26905
|
+
result.push(entry);
|
|
26906
|
+
continue;
|
|
26907
|
+
}
|
|
26908
|
+
const start = result.length;
|
|
26909
|
+
const length = entry.length;
|
|
26910
|
+
options.budget.allocateArrayLength(start + length);
|
|
26911
|
+
result.length += length;
|
|
26912
|
+
for (let index = 0; index < length; index++) {
|
|
26913
|
+
options.budget.visitNode();
|
|
26914
|
+
if (index in entry)
|
|
26915
|
+
result[start + index] = await readArrayElement(entry, index, options);
|
|
26916
|
+
}
|
|
26917
|
+
}
|
|
26918
|
+
return budgetProducedValue(result, options.budget);
|
|
26919
|
+
} finally {
|
|
26920
|
+
options.budget.setRetainedValues(retained, void 0);
|
|
26429
26921
|
}
|
|
26430
|
-
return budgetProducedValue(result, options.budget);
|
|
26431
26922
|
}
|
|
26432
|
-
case "concat":
|
|
26433
|
-
return budgetProducedValue(
|
|
26434
|
-
Reflect.apply(Array.prototype.concat, value, [...args]),
|
|
26435
|
-
options.budget
|
|
26436
|
-
);
|
|
26437
26923
|
case "splice": {
|
|
26438
|
-
const
|
|
26924
|
+
const length = value.length;
|
|
26925
|
+
const start = toIntegerOrInfinity(
|
|
26926
|
+
await sandboxNumber(args[0], options.budget, options.context)
|
|
26927
|
+
);
|
|
26928
|
+
const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
|
|
26929
|
+
const inserted = Math.max(args.length - 2, 0);
|
|
26930
|
+
const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(
|
|
26931
|
+
Math.max(
|
|
26932
|
+
toIntegerOrInfinity(
|
|
26933
|
+
await sandboxNumber(args[1], options.budget, options.context)
|
|
26934
|
+
),
|
|
26935
|
+
0
|
|
26936
|
+
),
|
|
26937
|
+
length - first
|
|
26938
|
+
);
|
|
26939
|
+
const nextLength = length + inserted - deleted;
|
|
26940
|
+
if (nextLength > Number.MAX_SAFE_INTEGER)
|
|
26941
|
+
throw new TypeError("Array-like length exceeds the safe integer limit.");
|
|
26942
|
+
options.budget.allocateArrayLength(deleted);
|
|
26943
|
+
const removed = new Array(deleted);
|
|
26944
|
+
const retained = {};
|
|
26945
|
+
options.budget.setRetainedValues(retained, () => [removed]);
|
|
26946
|
+
try {
|
|
26947
|
+
for (let index = 0; index < deleted; index++) {
|
|
26948
|
+
options.budget.visitNode();
|
|
26949
|
+
if (first + index in value)
|
|
26950
|
+
removed[index] = await readArrayElement(value, first + index, options);
|
|
26951
|
+
}
|
|
26952
|
+
if (inserted < deleted) {
|
|
26953
|
+
for (let index = first; index < length - deleted; index++)
|
|
26954
|
+
await moveArrayElement(value, index + deleted, index + inserted, options);
|
|
26955
|
+
for (let index = length; index > nextLength; index--)
|
|
26956
|
+
deleteArrayElement(value, index - 1, options);
|
|
26957
|
+
} else if (inserted > deleted) {
|
|
26958
|
+
for (let index = length - deleted; index > first; index--)
|
|
26959
|
+
await moveArrayElement(value, index + deleted - 1, index + inserted - 1, options);
|
|
26960
|
+
}
|
|
26961
|
+
for (let index = 0; index < inserted; index++)
|
|
26962
|
+
await writeArrayProperty(value, first + index, args[index + 2], options);
|
|
26963
|
+
await writeArrayProperty(value, "length", nextLength, options);
|
|
26964
|
+
} finally {
|
|
26965
|
+
options.budget.setRetainedValues(retained, void 0);
|
|
26966
|
+
}
|
|
26439
26967
|
budgetProducedValue(removed, options.budget);
|
|
26440
26968
|
budgetProducedValue(value, options.budget);
|
|
26441
26969
|
return removed;
|
|
26442
26970
|
}
|
|
26443
|
-
case "fill":
|
|
26444
|
-
|
|
26971
|
+
case "fill": {
|
|
26972
|
+
const length = value.length;
|
|
26973
|
+
const start = toIntegerOrInfinity(
|
|
26974
|
+
await sandboxNumber(args[1], options.budget, options.context)
|
|
26975
|
+
);
|
|
26976
|
+
const end = args[2] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[2], options.budget, options.context));
|
|
26977
|
+
const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
|
|
26978
|
+
const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
|
|
26979
|
+
for (let index = first; index < final; index++)
|
|
26980
|
+
await writeArrayProperty(value, index, args[0], options);
|
|
26445
26981
|
budgetProducedValue(value, options.budget);
|
|
26446
26982
|
return value;
|
|
26447
|
-
|
|
26448
|
-
|
|
26983
|
+
}
|
|
26984
|
+
case "copyWithin": {
|
|
26985
|
+
const length = value.length;
|
|
26986
|
+
const target = toIntegerOrInfinity(
|
|
26987
|
+
await sandboxNumber(args[0], options.budget, options.context)
|
|
26988
|
+
);
|
|
26989
|
+
const start = toIntegerOrInfinity(
|
|
26990
|
+
await sandboxNumber(args[1], options.budget, options.context)
|
|
26991
|
+
);
|
|
26992
|
+
const end = args[2] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[2], options.budget, options.context));
|
|
26993
|
+
let to = target < 0 ? Math.max(length + target, 0) : Math.min(target, length);
|
|
26994
|
+
let from = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
|
|
26995
|
+
const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
|
|
26996
|
+
let count = Math.min(final - from, length - to);
|
|
26997
|
+
const direction = from < to && to < from + count ? -1 : 1;
|
|
26998
|
+
if (direction < 0) {
|
|
26999
|
+
from += count - 1;
|
|
27000
|
+
to += count - 1;
|
|
27001
|
+
}
|
|
27002
|
+
while (count-- > 0) {
|
|
27003
|
+
await moveArrayElement(value, from, to, options);
|
|
27004
|
+
from += direction;
|
|
27005
|
+
to += direction;
|
|
27006
|
+
}
|
|
26449
27007
|
budgetProducedValue(value, options.budget);
|
|
26450
27008
|
return value;
|
|
26451
|
-
|
|
26452
|
-
|
|
26453
|
-
|
|
26454
|
-
|
|
27009
|
+
}
|
|
27010
|
+
case "at": {
|
|
27011
|
+
const length = value.length;
|
|
27012
|
+
const index = toIntegerOrInfinity(
|
|
27013
|
+
await sandboxNumber(args[0], options.budget, options.context)
|
|
26455
27014
|
);
|
|
27015
|
+
const actual = index < 0 ? length + index : index;
|
|
27016
|
+
return actual < 0 || actual >= length ? void 0 : budgetProducedValue(await readArrayElement(value, actual, options), options.budget);
|
|
27017
|
+
}
|
|
26456
27018
|
case "sort":
|
|
26457
|
-
|
|
26458
|
-
|
|
27019
|
+
await sortArray(
|
|
27020
|
+
value,
|
|
27021
|
+
args[0] === void 0 ? void 0 : getRequiredCallback(methodName, args[0]),
|
|
27022
|
+
options,
|
|
27023
|
+
stack
|
|
27024
|
+
);
|
|
27025
|
+
budgetProducedValue(value, options.budget);
|
|
27026
|
+
return value;
|
|
27027
|
+
case "reverse": {
|
|
27028
|
+
const length = value.length;
|
|
27029
|
+
let lowerValue;
|
|
27030
|
+
let upperValue;
|
|
27031
|
+
const release = retainValues(options.budget, () => [lowerValue, upperValue]);
|
|
27032
|
+
try {
|
|
27033
|
+
for (let lower = 0; lower < Math.floor(length / 2); lower++) {
|
|
27034
|
+
options.budget.visitNode();
|
|
27035
|
+
lowerValue = upperValue = void 0;
|
|
27036
|
+
const upper = length - lower - 1;
|
|
27037
|
+
const lowerExists = lower in value;
|
|
27038
|
+
lowerValue = lowerExists ? await readArrayElement(value, lower, options) : void 0;
|
|
27039
|
+
const upperExists = upper in value;
|
|
27040
|
+
upperValue = upperExists ? await readArrayElement(value, upper, options) : void 0;
|
|
27041
|
+
if (lowerExists && upperExists) {
|
|
27042
|
+
await writeArrayProperty(value, lower, upperValue, options);
|
|
27043
|
+
await writeArrayProperty(value, upper, lowerValue, options);
|
|
27044
|
+
} else if (!lowerExists && upperExists) {
|
|
27045
|
+
await writeArrayProperty(value, lower, upperValue, options);
|
|
27046
|
+
deleteArrayElement(value, upper, options);
|
|
27047
|
+
} else if (lowerExists) {
|
|
27048
|
+
deleteArrayElement(value, lower, options);
|
|
27049
|
+
await writeArrayProperty(value, upper, lowerValue, options);
|
|
27050
|
+
}
|
|
27051
|
+
}
|
|
26459
27052
|
budgetProducedValue(value, options.budget);
|
|
26460
27053
|
return value;
|
|
27054
|
+
} finally {
|
|
27055
|
+
release();
|
|
26461
27056
|
}
|
|
26462
|
-
|
|
26463
|
-
budgetProducedValue(value, options.budget);
|
|
26464
|
-
return value;
|
|
26465
|
-
case "reverse":
|
|
26466
|
-
Reflect.apply(Array.prototype.reverse, value, []);
|
|
26467
|
-
budgetProducedValue(value, options.budget);
|
|
26468
|
-
return value;
|
|
27057
|
+
}
|
|
26469
27058
|
case "toSorted": {
|
|
26470
27059
|
const length = value.length;
|
|
26471
27060
|
options.budget.allocateArrayLength(length);
|
|
26472
27061
|
const result = new Array(length);
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26476
|
-
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26480
|
-
|
|
27062
|
+
const release = retainValues(options.budget, () => [result]);
|
|
27063
|
+
try {
|
|
27064
|
+
for (let index = 0; index < length; index += 1) {
|
|
27065
|
+
options.budget.visitNode();
|
|
27066
|
+
result[index] = await readArrayElement(value, index, options);
|
|
27067
|
+
}
|
|
27068
|
+
await sortArray(
|
|
27069
|
+
result,
|
|
27070
|
+
args[0] === void 0 ? void 0 : getRequiredCallback(methodName, args[0]),
|
|
27071
|
+
options,
|
|
27072
|
+
stack
|
|
27073
|
+
);
|
|
27074
|
+
return budgetProducedValue(result, options.budget);
|
|
27075
|
+
} finally {
|
|
27076
|
+
release();
|
|
26481
27077
|
}
|
|
26482
|
-
return budgetProducedValue(result, options.budget);
|
|
26483
27078
|
}
|
|
26484
27079
|
case "toReversed": {
|
|
26485
27080
|
const length = value.length;
|
|
26486
27081
|
options.budget.allocateArrayLength(length);
|
|
26487
27082
|
const result = new Array(length);
|
|
26488
|
-
|
|
26489
|
-
|
|
26490
|
-
|
|
27083
|
+
const release = retainValues(options.budget, () => [result]);
|
|
27084
|
+
try {
|
|
27085
|
+
for (let index = 0; index < length; index += 1) {
|
|
27086
|
+
options.budget.visitNode();
|
|
27087
|
+
result[index] = await readArrayElement(value, length - index - 1, options);
|
|
27088
|
+
}
|
|
27089
|
+
return budgetProducedValue(result, options.budget);
|
|
27090
|
+
} finally {
|
|
27091
|
+
release();
|
|
26491
27092
|
}
|
|
26492
|
-
return budgetProducedValue(result, options.budget);
|
|
26493
27093
|
}
|
|
26494
27094
|
case "toSpliced": {
|
|
26495
27095
|
const length = value.length;
|
|
26496
|
-
const start = toIntegerOrInfinity(
|
|
27096
|
+
const start = toIntegerOrInfinity(
|
|
27097
|
+
await sandboxNumber(args[0], options.budget, options.context)
|
|
27098
|
+
);
|
|
26497
27099
|
const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
|
|
26498
27100
|
const inserted = Math.max(args.length - 2, 0);
|
|
26499
|
-
const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(
|
|
27101
|
+
const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(
|
|
27102
|
+
Math.max(
|
|
27103
|
+
toIntegerOrInfinity(
|
|
27104
|
+
await sandboxNumber(args[1], options.budget, options.context)
|
|
27105
|
+
),
|
|
27106
|
+
0
|
|
27107
|
+
),
|
|
27108
|
+
length - first
|
|
27109
|
+
);
|
|
26500
27110
|
const resultLength = length + inserted - deleted;
|
|
26501
|
-
if (resultLength > Number.MAX_SAFE_INTEGER)
|
|
27111
|
+
if (resultLength > Number.MAX_SAFE_INTEGER)
|
|
27112
|
+
throw new TypeError("Array-like length exceeds the safe integer limit.");
|
|
26502
27113
|
options.budget.allocateArrayLength(resultLength);
|
|
26503
27114
|
const result = new Array(resultLength);
|
|
26504
|
-
|
|
26505
|
-
|
|
26506
|
-
|
|
27115
|
+
const release = retainValues(options.budget, () => [result]);
|
|
27116
|
+
try {
|
|
27117
|
+
for (let index = 0; index < resultLength; index += 1) {
|
|
27118
|
+
options.budget.visitNode();
|
|
27119
|
+
result[index] = index < first ? await readArrayElement(value, index, options) : index < first + inserted ? args[index - first + 2] : await readArrayElement(value, index - inserted + deleted, options);
|
|
27120
|
+
}
|
|
27121
|
+
return budgetProducedValue(result, options.budget);
|
|
27122
|
+
} finally {
|
|
27123
|
+
release();
|
|
26507
27124
|
}
|
|
26508
|
-
return budgetProducedValue(result, options.budget);
|
|
26509
27125
|
}
|
|
26510
27126
|
case "with": {
|
|
26511
27127
|
const length = value.length;
|
|
26512
|
-
const index = toIntegerOrInfinity(
|
|
27128
|
+
const index = toIntegerOrInfinity(
|
|
27129
|
+
options.context === void 0 ? args[0] : await sandboxNumber(args[0], options.budget, options.context)
|
|
27130
|
+
);
|
|
26513
27131
|
const actualIndex = index < 0 ? length + index : index;
|
|
26514
27132
|
if (actualIndex < 0 || actualIndex >= length) {
|
|
26515
27133
|
throw new RangeError("Invalid index");
|
|
26516
27134
|
}
|
|
26517
27135
|
options.budget.allocateArrayLength(length);
|
|
26518
27136
|
const result = [];
|
|
26519
|
-
|
|
26520
|
-
|
|
26521
|
-
|
|
27137
|
+
const release = retainValues(options.budget, () => [result]);
|
|
27138
|
+
try {
|
|
27139
|
+
for (let position = 0; position < length; position += 1) {
|
|
27140
|
+
options.budget.visitNode();
|
|
27141
|
+
result[position] = position === actualIndex ? args[1] : await readArrayElement(value, position, options);
|
|
27142
|
+
}
|
|
27143
|
+
return budgetProducedValue(result, options.budget);
|
|
27144
|
+
} finally {
|
|
27145
|
+
release();
|
|
26522
27146
|
}
|
|
26523
|
-
return budgetProducedValue(result, options.budget);
|
|
26524
27147
|
}
|
|
26525
27148
|
case "push": {
|
|
26526
|
-
const nextLength = appendArrayValues(value, args);
|
|
27149
|
+
const nextLength = await appendArrayValues(value, args, options);
|
|
26527
27150
|
budgetProducedValue(value, options.budget);
|
|
26528
27151
|
return nextLength;
|
|
26529
27152
|
}
|
|
26530
27153
|
case "pop":
|
|
26531
|
-
|
|
26532
|
-
|
|
26533
|
-
|
|
27154
|
+
case "shift": {
|
|
27155
|
+
const length = value.length;
|
|
27156
|
+
if (length === 0) {
|
|
27157
|
+
await writeArrayProperty(value, "length", 0, options);
|
|
27158
|
+
return void 0;
|
|
27159
|
+
}
|
|
27160
|
+
const result = await readArrayElement(value, methodName === "pop" ? length - 1 : 0, options);
|
|
27161
|
+
const retained = {};
|
|
27162
|
+
options.budget.setRetainedValues(retained, () => [result]);
|
|
27163
|
+
try {
|
|
27164
|
+
if (methodName === "shift")
|
|
27165
|
+
for (let index = 1; index < length; index++)
|
|
27166
|
+
await moveArrayElement(value, index, index - 1, options);
|
|
27167
|
+
deleteArrayElement(value, length - 1, options);
|
|
27168
|
+
await writeArrayProperty(value, "length", length - 1, options);
|
|
27169
|
+
return budgetProducedValue(result, options.budget);
|
|
27170
|
+
} finally {
|
|
27171
|
+
options.budget.setRetainedValues(retained, void 0);
|
|
27172
|
+
}
|
|
27173
|
+
}
|
|
26534
27174
|
case "unshift": {
|
|
26535
|
-
const nextLength = prependArrayValues(value, args);
|
|
27175
|
+
const nextLength = await prependArrayValues(value, args, options);
|
|
26536
27176
|
budgetProducedValue(value, options.budget);
|
|
26537
27177
|
return nextLength;
|
|
26538
27178
|
}
|
|
26539
27179
|
}
|
|
26540
27180
|
}
|
|
26541
|
-
function appendArrayValues(target, values) {
|
|
27181
|
+
async function appendArrayValues(target, values, options) {
|
|
26542
27182
|
let length = target.length;
|
|
26543
|
-
if (length + values.length > Number.MAX_SAFE_INTEGER)
|
|
27183
|
+
if (length + values.length > Number.MAX_SAFE_INTEGER)
|
|
27184
|
+
throw new TypeError("Array-like length exceeds the safe integer limit.");
|
|
26544
27185
|
for (const value of values) {
|
|
26545
|
-
target
|
|
27186
|
+
await writeArrayProperty(target, length++, value, options);
|
|
26546
27187
|
}
|
|
26547
|
-
target
|
|
27188
|
+
await writeArrayProperty(target, "length", length, options);
|
|
26548
27189
|
return length;
|
|
26549
27190
|
}
|
|
26550
|
-
function prependArrayValues(target, values) {
|
|
27191
|
+
async function prependArrayValues(target, values, options) {
|
|
26551
27192
|
const originalLength = target.length;
|
|
26552
27193
|
const length = originalLength + values.length;
|
|
26553
|
-
if (length > Number.MAX_SAFE_INTEGER)
|
|
27194
|
+
if (length > Number.MAX_SAFE_INTEGER)
|
|
27195
|
+
throw new TypeError("Array-like length exceeds the safe integer limit.");
|
|
26554
27196
|
for (let index = values.length === 0 ? -1 : originalLength - 1; index >= 0; index -= 1) {
|
|
26555
27197
|
const targetIndex = index + values.length;
|
|
26556
|
-
|
|
26557
|
-
target[targetIndex] = target[index];
|
|
26558
|
-
} else {
|
|
26559
|
-
delete target[targetIndex];
|
|
26560
|
-
}
|
|
27198
|
+
await moveArrayElement(target, index, targetIndex, options);
|
|
26561
27199
|
}
|
|
26562
27200
|
for (let index = 0; index < values.length; index += 1) {
|
|
26563
|
-
target
|
|
27201
|
+
await writeArrayProperty(target, index, values[index], options);
|
|
26564
27202
|
}
|
|
26565
|
-
target
|
|
27203
|
+
await writeArrayProperty(target, "length", length, options);
|
|
26566
27204
|
return length;
|
|
26567
27205
|
}
|
|
26568
27206
|
function isCallbackArrayMethod(methodName) {
|
|
@@ -26577,6 +27215,33 @@ function getRequiredCallback(methodName, value) {
|
|
|
26577
27215
|
}
|
|
26578
27216
|
return value;
|
|
26579
27217
|
}
|
|
27218
|
+
function readArrayElement(value, index, options) {
|
|
27219
|
+
const receiver = arrayLikeSources.get(value) ?? value;
|
|
27220
|
+
return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, index) : getSandboxDataProperty(receiver, index, options.budget);
|
|
27221
|
+
}
|
|
27222
|
+
function writeArrayProperty(value, key, entry, options) {
|
|
27223
|
+
options.budget.visitNode();
|
|
27224
|
+
const receiver = arrayLikeSources.get(value) ?? value;
|
|
27225
|
+
if (Array.isArray(receiver)) {
|
|
27226
|
+
if (key === "length") options.budget.allocateArrayLength(Number(entry));
|
|
27227
|
+
else if (typeof key === "number") options.budget.allocateArrayLength(key + 1);
|
|
27228
|
+
}
|
|
27229
|
+
if (options.setProperty !== void 0) return options.setProperty(receiver, String(key), entry);
|
|
27230
|
+
if (!Reflect.set(receiver, key, entry))
|
|
27231
|
+
throw new TypeError(`Cannot assign to read only property '${key}'.`);
|
|
27232
|
+
}
|
|
27233
|
+
function deleteArrayElement(value, index, options) {
|
|
27234
|
+
options.budget.visitNode();
|
|
27235
|
+
const receiver = arrayLikeSources.get(value) ?? value;
|
|
27236
|
+
const deleted = options.deleteProperty === void 0 ? Reflect.deleteProperty(receiver, String(index)) : options.deleteProperty(receiver, String(index));
|
|
27237
|
+
if (!deleted) throw new TypeError(`Cannot delete property '${index}'.`);
|
|
27238
|
+
}
|
|
27239
|
+
async function moveArrayElement(value, from, to, options) {
|
|
27240
|
+
options.budget.visitNode();
|
|
27241
|
+
if (from in value)
|
|
27242
|
+
await writeArrayProperty(value, to, await readArrayElement(value, from, options), options);
|
|
27243
|
+
else deleteArrayElement(value, to, options);
|
|
27244
|
+
}
|
|
26580
27245
|
async function mapArray(value, callback, options, stack, thisValue) {
|
|
26581
27246
|
const length = value.length;
|
|
26582
27247
|
options.budget.allocateArrayLength(length);
|
|
@@ -26590,7 +27255,7 @@ async function mapArray(value, callback, options, stack, thisValue) {
|
|
|
26590
27255
|
}
|
|
26591
27256
|
result[index] = await callArrayCallback(
|
|
26592
27257
|
callback,
|
|
26593
|
-
value
|
|
27258
|
+
await readArrayElement(value, index, options),
|
|
26594
27259
|
index,
|
|
26595
27260
|
value,
|
|
26596
27261
|
options,
|
|
@@ -26613,7 +27278,7 @@ async function filterArray(value, callback, options, stack, thisValue) {
|
|
|
26613
27278
|
if (!(index in value)) {
|
|
26614
27279
|
continue;
|
|
26615
27280
|
}
|
|
26616
|
-
const entry = value
|
|
27281
|
+
const entry = await readArrayElement(value, index, options);
|
|
26617
27282
|
if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
|
|
26618
27283
|
result.push(entry);
|
|
26619
27284
|
}
|
|
@@ -26627,7 +27292,7 @@ async function findInArray(value, callback, options, stack, thisValue) {
|
|
|
26627
27292
|
const length = value.length;
|
|
26628
27293
|
for (let index = 0; index < length; index += 1) {
|
|
26629
27294
|
options.budget.visitNode();
|
|
26630
|
-
const entry =
|
|
27295
|
+
const entry = await readArrayElement(value, index, options);
|
|
26631
27296
|
if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
|
|
26632
27297
|
return entry;
|
|
26633
27298
|
}
|
|
@@ -26638,7 +27303,7 @@ async function findIndexInArray(value, callback, options, stack, thisValue) {
|
|
|
26638
27303
|
const length = value.length;
|
|
26639
27304
|
for (let index = 0; index < length; index += 1) {
|
|
26640
27305
|
options.budget.visitNode();
|
|
26641
|
-
const entry =
|
|
27306
|
+
const entry = await readArrayElement(value, index, options);
|
|
26642
27307
|
if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
|
|
26643
27308
|
return index;
|
|
26644
27309
|
}
|
|
@@ -26649,7 +27314,7 @@ async function findLastInArray(value, callback, options, stack, thisValue) {
|
|
|
26649
27314
|
const length = value.length;
|
|
26650
27315
|
for (let index = length - 1; index >= 0; index -= 1) {
|
|
26651
27316
|
options.budget.visitNode();
|
|
26652
|
-
const entry =
|
|
27317
|
+
const entry = await readArrayElement(value, index, options);
|
|
26653
27318
|
if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
|
|
26654
27319
|
return entry;
|
|
26655
27320
|
}
|
|
@@ -26660,7 +27325,7 @@ async function findLastIndexInArray(value, callback, options, stack, thisValue)
|
|
|
26660
27325
|
const length = value.length;
|
|
26661
27326
|
for (let index = length - 1; index >= 0; index -= 1) {
|
|
26662
27327
|
options.budget.visitNode();
|
|
26663
|
-
const entry =
|
|
27328
|
+
const entry = await readArrayElement(value, index, options);
|
|
26664
27329
|
if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
|
|
26665
27330
|
return index;
|
|
26666
27331
|
}
|
|
@@ -26674,7 +27339,15 @@ async function someInArray(value, callback, options, stack, thisValue) {
|
|
|
26674
27339
|
if (!(index in value)) {
|
|
26675
27340
|
continue;
|
|
26676
27341
|
}
|
|
26677
|
-
if (await callArrayCallback(
|
|
27342
|
+
if (await callArrayCallback(
|
|
27343
|
+
callback,
|
|
27344
|
+
await readArrayElement(value, index, options),
|
|
27345
|
+
index,
|
|
27346
|
+
value,
|
|
27347
|
+
options,
|
|
27348
|
+
stack,
|
|
27349
|
+
thisValue
|
|
27350
|
+
)) {
|
|
26678
27351
|
return true;
|
|
26679
27352
|
}
|
|
26680
27353
|
}
|
|
@@ -26687,7 +27360,15 @@ async function everyInArray(value, callback, options, stack, thisValue) {
|
|
|
26687
27360
|
if (!(index in value)) {
|
|
26688
27361
|
continue;
|
|
26689
27362
|
}
|
|
26690
|
-
if (!await callArrayCallback(
|
|
27363
|
+
if (!await callArrayCallback(
|
|
27364
|
+
callback,
|
|
27365
|
+
await readArrayElement(value, index, options),
|
|
27366
|
+
index,
|
|
27367
|
+
value,
|
|
27368
|
+
options,
|
|
27369
|
+
stack,
|
|
27370
|
+
thisValue
|
|
27371
|
+
)) {
|
|
26691
27372
|
return false;
|
|
26692
27373
|
}
|
|
26693
27374
|
}
|
|
@@ -26702,7 +27383,15 @@ async function reduceArray(value, callback, hasInitialValue, initialValue, optio
|
|
|
26702
27383
|
if (start < 0) {
|
|
26703
27384
|
throw new TypeError("Reduce of empty array with no initial value.");
|
|
26704
27385
|
}
|
|
26705
|
-
return reduceFromLeft(
|
|
27386
|
+
return reduceFromLeft(
|
|
27387
|
+
value,
|
|
27388
|
+
callback,
|
|
27389
|
+
await readArrayElement(value, start, options),
|
|
27390
|
+
start + 1,
|
|
27391
|
+
length,
|
|
27392
|
+
options,
|
|
27393
|
+
stack
|
|
27394
|
+
);
|
|
26706
27395
|
}
|
|
26707
27396
|
async function reduceRightArray(value, callback, hasInitialValue, initialValue, options, stack) {
|
|
26708
27397
|
const length = value.length;
|
|
@@ -26713,7 +27402,15 @@ async function reduceRightArray(value, callback, hasInitialValue, initialValue,
|
|
|
26713
27402
|
if (start < 0) {
|
|
26714
27403
|
throw new TypeError("Reduce of empty array with no initial value.");
|
|
26715
27404
|
}
|
|
26716
|
-
return reduceFromRight(
|
|
27405
|
+
return reduceFromRight(
|
|
27406
|
+
value,
|
|
27407
|
+
callback,
|
|
27408
|
+
await readArrayElement(value, start, options),
|
|
27409
|
+
start - 1,
|
|
27410
|
+
length,
|
|
27411
|
+
options,
|
|
27412
|
+
stack
|
|
27413
|
+
);
|
|
26717
27414
|
}
|
|
26718
27415
|
async function reduceFromLeft(value, callback, accumulator, startIndex, length, options, stack) {
|
|
26719
27416
|
let current = accumulator;
|
|
@@ -26725,7 +27422,16 @@ async function reduceFromLeft(value, callback, accumulator, startIndex, length,
|
|
|
26725
27422
|
if (!(index in value)) {
|
|
26726
27423
|
continue;
|
|
26727
27424
|
}
|
|
26728
|
-
current = await options.callClosure(
|
|
27425
|
+
current = await options.callClosure(
|
|
27426
|
+
callback,
|
|
27427
|
+
[
|
|
27428
|
+
current,
|
|
27429
|
+
await readArrayElement(value, index, options),
|
|
27430
|
+
index,
|
|
27431
|
+
arrayLikeSources.get(value) ?? value
|
|
27432
|
+
],
|
|
27433
|
+
stack
|
|
27434
|
+
);
|
|
26729
27435
|
}
|
|
26730
27436
|
return current;
|
|
26731
27437
|
} finally {
|
|
@@ -26742,7 +27448,16 @@ async function reduceFromRight(value, callback, accumulator, startIndex, length,
|
|
|
26742
27448
|
if (!(index in value)) {
|
|
26743
27449
|
continue;
|
|
26744
27450
|
}
|
|
26745
|
-
current = await options.callClosure(
|
|
27451
|
+
current = await options.callClosure(
|
|
27452
|
+
callback,
|
|
27453
|
+
[
|
|
27454
|
+
current,
|
|
27455
|
+
await readArrayElement(value, index, options),
|
|
27456
|
+
index,
|
|
27457
|
+
arrayLikeSources.get(value) ?? value
|
|
27458
|
+
],
|
|
27459
|
+
stack
|
|
27460
|
+
);
|
|
26746
27461
|
}
|
|
26747
27462
|
return current;
|
|
26748
27463
|
} finally {
|
|
@@ -26756,7 +27471,15 @@ async function forEachArray(value, callback, options, stack, thisValue) {
|
|
|
26756
27471
|
if (!(index in value)) {
|
|
26757
27472
|
continue;
|
|
26758
27473
|
}
|
|
26759
|
-
await callArrayCallback(
|
|
27474
|
+
await callArrayCallback(
|
|
27475
|
+
callback,
|
|
27476
|
+
await readArrayElement(value, index, options),
|
|
27477
|
+
index,
|
|
27478
|
+
value,
|
|
27479
|
+
options,
|
|
27480
|
+
stack,
|
|
27481
|
+
thisValue
|
|
27482
|
+
);
|
|
26760
27483
|
}
|
|
26761
27484
|
}
|
|
26762
27485
|
async function flatMapArray(value, callback, options, stack, thisValue) {
|
|
@@ -26771,7 +27494,7 @@ async function flatMapArray(value, callback, options, stack, thisValue) {
|
|
|
26771
27494
|
}
|
|
26772
27495
|
const mapped = await callArrayCallback(
|
|
26773
27496
|
callback,
|
|
26774
|
-
value
|
|
27497
|
+
await readArrayElement(value, index, options),
|
|
26775
27498
|
index,
|
|
26776
27499
|
value,
|
|
26777
27500
|
options,
|
|
@@ -26784,7 +27507,7 @@ async function flatMapArray(value, callback, options, stack, thisValue) {
|
|
|
26784
27507
|
if (!(mappedIndex in mapped)) {
|
|
26785
27508
|
continue;
|
|
26786
27509
|
}
|
|
26787
|
-
result.push(mapped
|
|
27510
|
+
result.push(await readArrayElement(mapped, mappedIndex, options));
|
|
26788
27511
|
options.budget.allocateArrayLength(result.length);
|
|
26789
27512
|
}
|
|
26790
27513
|
continue;
|
|
@@ -26797,23 +27520,31 @@ async function flatMapArray(value, callback, options, stack, thisValue) {
|
|
|
26797
27520
|
options.budget.setRetainedValues(result, void 0);
|
|
26798
27521
|
}
|
|
26799
27522
|
}
|
|
26800
|
-
function flattenArray(value, depth,
|
|
27523
|
+
async function flattenArray(value, depth, options) {
|
|
26801
27524
|
const result = [];
|
|
26802
|
-
|
|
26803
|
-
|
|
27525
|
+
const retained = {};
|
|
27526
|
+
options.budget.setRetainedValues(retained, () => [result]);
|
|
27527
|
+
try {
|
|
27528
|
+
await appendFlattenedEntries(value, depth, result, options);
|
|
27529
|
+
return result;
|
|
27530
|
+
} finally {
|
|
27531
|
+
options.budget.setRetainedValues(retained, void 0);
|
|
27532
|
+
}
|
|
26804
27533
|
}
|
|
26805
|
-
function appendFlattenedEntries(value, depth, result,
|
|
26806
|
-
|
|
27534
|
+
async function appendFlattenedEntries(value, depth, result, options) {
|
|
27535
|
+
const length = value.length;
|
|
27536
|
+
for (let index = 0; index < length; index += 1) {
|
|
27537
|
+
options.budget.visitNode();
|
|
26807
27538
|
if (!(index in value)) {
|
|
26808
27539
|
continue;
|
|
26809
27540
|
}
|
|
26810
|
-
const entry = value
|
|
27541
|
+
const entry = await readArrayElement(value, index, options);
|
|
26811
27542
|
if (depth > 0 && Array.isArray(entry)) {
|
|
26812
|
-
appendFlattenedEntries(entry, depth - 1, result,
|
|
27543
|
+
await appendFlattenedEntries(entry, depth - 1, result, options);
|
|
26813
27544
|
continue;
|
|
26814
27545
|
}
|
|
26815
27546
|
result.push(entry);
|
|
26816
|
-
budget.allocateArrayLength(result.length);
|
|
27547
|
+
options.budget.allocateArrayLength(result.length);
|
|
26817
27548
|
}
|
|
26818
27549
|
}
|
|
26819
27550
|
async function sortArray(value, comparator, options, stack) {
|
|
@@ -26828,7 +27559,7 @@ async function sortArray(value, comparator, options, stack) {
|
|
|
26828
27559
|
if (!(index in value)) {
|
|
26829
27560
|
continue;
|
|
26830
27561
|
}
|
|
26831
|
-
const entry = value
|
|
27562
|
+
const entry = await readArrayElement(value, index, options);
|
|
26832
27563
|
if (entry === void 0) {
|
|
26833
27564
|
undefinedCount += 1;
|
|
26834
27565
|
continue;
|
|
@@ -26846,14 +27577,14 @@ async function sortArray(value, comparator, options, stack) {
|
|
|
26846
27577
|
}
|
|
26847
27578
|
currentEntry = void 0;
|
|
26848
27579
|
for (let index = 0; index < definedValues.length; index += 1) {
|
|
26849
|
-
value
|
|
27580
|
+
await writeArrayProperty(value, index, definedValues[index], options);
|
|
26850
27581
|
}
|
|
26851
27582
|
for (let index = 0; index < undefinedCount; index += 1) {
|
|
26852
|
-
value
|
|
27583
|
+
await writeArrayProperty(value, definedValues.length + index, void 0, options);
|
|
26853
27584
|
}
|
|
26854
27585
|
for (let index = definedValues.length + undefinedCount; index < length; index += 1) {
|
|
26855
27586
|
options.budget.visitNode();
|
|
26856
|
-
|
|
27587
|
+
deleteArrayElement(value, index, options);
|
|
26857
27588
|
}
|
|
26858
27589
|
} finally {
|
|
26859
27590
|
options.budget.setRetainedValues(definedValues, void 0);
|
|
@@ -26861,11 +27592,30 @@ async function sortArray(value, comparator, options, stack) {
|
|
|
26861
27592
|
}
|
|
26862
27593
|
async function compareEntries(left, right, comparator, options, stack) {
|
|
26863
27594
|
options.budget.visitNode();
|
|
26864
|
-
|
|
27595
|
+
if (comparator === void 0) {
|
|
27596
|
+
const leftString = await sandboxString(left, options.budget, options.context);
|
|
27597
|
+
const release = retainValues(options.budget, () => [leftString]);
|
|
27598
|
+
try {
|
|
27599
|
+
const rightString = await sandboxString(right, options.budget, options.context);
|
|
27600
|
+
return leftString < rightString ? -1 : leftString > rightString ? 1 : 0;
|
|
27601
|
+
} finally {
|
|
27602
|
+
release();
|
|
27603
|
+
}
|
|
27604
|
+
}
|
|
27605
|
+
const result = await sandboxNumber(
|
|
27606
|
+
await options.callClosure(comparator, [left, right], stack),
|
|
27607
|
+
options.budget,
|
|
27608
|
+
options.context
|
|
27609
|
+
);
|
|
26865
27610
|
return Number.isNaN(result) ? 0 : result;
|
|
26866
27611
|
}
|
|
26867
27612
|
async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
|
|
26868
|
-
return options.callClosure(
|
|
27613
|
+
return options.callClosure(
|
|
27614
|
+
callback,
|
|
27615
|
+
[value, index, arrayLikeSources.get(array) ?? array],
|
|
27616
|
+
stack,
|
|
27617
|
+
thisValue
|
|
27618
|
+
);
|
|
26869
27619
|
}
|
|
26870
27620
|
function findNextDefinedIndex(value, startIndex, direction, length, budget) {
|
|
26871
27621
|
for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
|
|
@@ -26950,7 +27700,8 @@ function getFunctionMember(target, property, options) {
|
|
|
26950
27700
|
while (current !== null) {
|
|
26951
27701
|
if (isGuestClosure(current)) {
|
|
26952
27702
|
const value = getGuestFunctionProperty(current, String(property));
|
|
26953
|
-
if (value !== void 0 || Object.hasOwn(current.properties ?? {}, String(property)))
|
|
27703
|
+
if (value !== void 0 || Object.hasOwn(current.properties ?? {}, String(property)))
|
|
27704
|
+
return value;
|
|
26954
27705
|
} else if (isSandboxClosure(current)) {
|
|
26955
27706
|
if (current.properties !== void 0 && Object.hasOwn(current.properties, String(property)))
|
|
26956
27707
|
return current.properties[String(property)];
|
|
@@ -26966,7 +27717,8 @@ function getFunctionMember(target, property, options) {
|
|
|
26966
27717
|
}
|
|
26967
27718
|
}
|
|
26968
27719
|
if (current === null) return void 0;
|
|
26969
|
-
if (property === "toString" && runResources.getStore()?.functionSourceText === false)
|
|
27720
|
+
if (property === "toString" && runResources.getStore()?.functionSourceText === false)
|
|
27721
|
+
return void 0;
|
|
26970
27722
|
if (!isFunctionMethodName(property)) {
|
|
26971
27723
|
return void 0;
|
|
26972
27724
|
}
|
|
@@ -26974,13 +27726,13 @@ function getFunctionMember(target, property, options) {
|
|
|
26974
27726
|
sandbox: true,
|
|
26975
27727
|
name: `Function#${property}`,
|
|
26976
27728
|
...property === "toString" ? { length: 0 } : {},
|
|
26977
|
-
call: (args, context) => callFunctionMethod(context?.thisValue, property, args, options, context?.stack ?? [])
|
|
27729
|
+
call: (args, context) => callFunctionMethod(context?.thisValue, property, args, options, context?.stack ?? [], context)
|
|
26978
27730
|
});
|
|
26979
27731
|
}
|
|
26980
27732
|
function isFunctionMethodName(property) {
|
|
26981
27733
|
return typeof property === "string" && functionMethodNames.has(property);
|
|
26982
27734
|
}
|
|
26983
|
-
function callFunctionMethod(target, methodName, args, options, stack) {
|
|
27735
|
+
function callFunctionMethod(target, methodName, args, options, stack, context) {
|
|
26984
27736
|
if (!isSandboxClosure(target)) {
|
|
26985
27737
|
throw new TypeError(`Function#${methodName} requires a callable receiver.`);
|
|
26986
27738
|
}
|
|
@@ -26991,28 +27743,46 @@ function callFunctionMethod(target, methodName, args, options, stack) {
|
|
|
26991
27743
|
const thisValue = args[0];
|
|
26992
27744
|
if (methodName === "bind") {
|
|
26993
27745
|
const boundArgs = args.slice(1);
|
|
26994
|
-
const
|
|
26995
|
-
|
|
26996
|
-
|
|
26997
|
-
|
|
26998
|
-
|
|
26999
|
-
|
|
27000
|
-
|
|
27001
|
-
|
|
27002
|
-
|
|
27003
|
-
construct
|
|
27004
|
-
|
|
27005
|
-
|
|
27006
|
-
|
|
27007
|
-
|
|
27008
|
-
|
|
27009
|
-
|
|
27010
|
-
|
|
27011
|
-
|
|
27012
|
-
|
|
27013
|
-
|
|
27014
|
-
|
|
27015
|
-
|
|
27746
|
+
const bind = (length, name) => {
|
|
27747
|
+
const bound = createSandboxClosure({
|
|
27748
|
+
guest: true,
|
|
27749
|
+
sandbox: true,
|
|
27750
|
+
name: `bound ${name}`,
|
|
27751
|
+
length,
|
|
27752
|
+
boundTarget: target,
|
|
27753
|
+
retainedValues: () => [target, thisValue, ...boundArgs, bound.name],
|
|
27754
|
+
call: (callArgs, context2) => options.callClosure(target, [...boundArgs, ...callArgs], context2?.stack ?? [], thisValue),
|
|
27755
|
+
...target.construct === void 0 ? {} : {
|
|
27756
|
+
construct: (callArgs, context2) => options.callClosure(
|
|
27757
|
+
target,
|
|
27758
|
+
[...boundArgs, ...callArgs],
|
|
27759
|
+
context2?.stack ?? [],
|
|
27760
|
+
void 0,
|
|
27761
|
+
true,
|
|
27762
|
+
context2?.newTarget === bound ? target : context2?.newTarget
|
|
27763
|
+
)
|
|
27764
|
+
}
|
|
27765
|
+
});
|
|
27766
|
+
if (hasExplicitSandboxPrototype(target))
|
|
27767
|
+
setSandboxPrototype(bound, getSandboxPrototype(target, options.budget), options.budget);
|
|
27768
|
+
return bound;
|
|
27769
|
+
};
|
|
27770
|
+
if (context?.getProperty === void 0)
|
|
27771
|
+
return bind(
|
|
27772
|
+
target.length === void 0 ? void 0 : Math.max(0, target.length - boundArgs.length),
|
|
27773
|
+
target.name ?? ""
|
|
27774
|
+
);
|
|
27775
|
+
return (async () => {
|
|
27776
|
+
const properties = target.properties;
|
|
27777
|
+
const defaultName = target.name;
|
|
27778
|
+
const hasLength = !isGuestClosure(target) || target.properties === void 0 || Object.hasOwn(target.properties, "length");
|
|
27779
|
+
const length = hasLength ? await context.getProperty(target, "length") : void 0;
|
|
27780
|
+
const name = !isGuestClosure(target) && !Object.hasOwn(properties ?? {}, "name") ? defaultName : await context.getProperty(target, "name");
|
|
27781
|
+
return bind(
|
|
27782
|
+
typeof length === "number" && !Number.isNaN(length) ? Math.max(0, Math.trunc(length) - boundArgs.length) : 0,
|
|
27783
|
+
typeof name === "string" ? name : ""
|
|
27784
|
+
);
|
|
27785
|
+
})();
|
|
27016
27786
|
}
|
|
27017
27787
|
if (methodName === "call") {
|
|
27018
27788
|
return options.callClosure(target, args.slice(1), stack, thisValue);
|
|
@@ -27024,7 +27794,24 @@ function callFunctionMethod(target, methodName, args, options, stack) {
|
|
|
27024
27794
|
if (!Array.isArray(applyArgs)) {
|
|
27025
27795
|
throw new TypeError("Function#apply requires an array or nullish arguments value.");
|
|
27026
27796
|
}
|
|
27027
|
-
|
|
27797
|
+
if (context?.getProperty === void 0)
|
|
27798
|
+
return options.callClosure(target, applyArgs, stack, thisValue);
|
|
27799
|
+
return (async () => {
|
|
27800
|
+
const values = [];
|
|
27801
|
+
const length = applyArgs.length;
|
|
27802
|
+
options.budget?.allocateArrayLength(length);
|
|
27803
|
+
const retained = {};
|
|
27804
|
+
options.budget?.setRetainedValues(retained, () => values);
|
|
27805
|
+
try {
|
|
27806
|
+
for (let index = 0; index < length; index++) {
|
|
27807
|
+
options.budget?.visitNode();
|
|
27808
|
+
values.push(await context.getProperty(applyArgs, index));
|
|
27809
|
+
}
|
|
27810
|
+
return await options.callClosure(target, values, stack, thisValue);
|
|
27811
|
+
} finally {
|
|
27812
|
+
options.budget?.setRetainedValues(retained, void 0);
|
|
27813
|
+
}
|
|
27814
|
+
})();
|
|
27028
27815
|
}
|
|
27029
27816
|
|
|
27030
27817
|
// packages/safe-js/src/interp/methods/collection-callback.ts
|
|
@@ -27336,15 +28123,24 @@ function createCollectionGlobals(options) {
|
|
|
27336
28123
|
context,
|
|
27337
28124
|
retainedValues: () => [key, value],
|
|
27338
28125
|
append: (entry) => {
|
|
27339
|
-
if (typeof entry !== "object" || entry === null)
|
|
27340
|
-
|
|
27341
|
-
|
|
27342
|
-
|
|
27343
|
-
|
|
27344
|
-
|
|
27345
|
-
|
|
27346
|
-
|
|
27347
|
-
|
|
28126
|
+
if (typeof entry !== "object" || entry === null)
|
|
28127
|
+
throw new TypeError("Map constructor requires entry objects.");
|
|
28128
|
+
const store = (entryValue) => {
|
|
28129
|
+
value = entryValue;
|
|
28130
|
+
const added = map.entries.has(key) ? 0 : 1;
|
|
28131
|
+
const growth = added + (options.budget.limits.dataSize === void 0 ? 0 : measureSandboxData([key, value]));
|
|
28132
|
+
options.budget.allocateCollectionEntries(map.entries.size + added);
|
|
28133
|
+
map.entries.set(key, value);
|
|
28134
|
+
key = value = void 0;
|
|
28135
|
+
return growth;
|
|
28136
|
+
};
|
|
28137
|
+
const readValue = (entryKey) => {
|
|
28138
|
+
key = entryKey;
|
|
28139
|
+
const result2 = context?.getProperty !== void 0 ? context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, options.budget);
|
|
28140
|
+
return result2 instanceof Promise ? result2.then(store) : store(result2);
|
|
28141
|
+
};
|
|
28142
|
+
const result = context?.getProperty !== void 0 ? context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, options.budget);
|
|
28143
|
+
return result instanceof Promise ? result.then(readValue) : readValue(result);
|
|
27348
28144
|
}
|
|
27349
28145
|
});
|
|
27350
28146
|
},
|
|
@@ -27382,7 +28178,13 @@ function isSandboxMapConstructor(value) {
|
|
|
27382
28178
|
function isSandboxSetConstructor(value) {
|
|
27383
28179
|
return typeof value === "object" && value !== null && setConstructors.has(value);
|
|
27384
28180
|
}
|
|
27385
|
-
function populateCollection(source, collection, {
|
|
28181
|
+
function populateCollection(source, collection, {
|
|
28182
|
+
name,
|
|
28183
|
+
budget,
|
|
28184
|
+
context,
|
|
28185
|
+
append,
|
|
28186
|
+
retainedValues
|
|
28187
|
+
}) {
|
|
27386
28188
|
budget.allocateCollectionEntries(0);
|
|
27387
28189
|
if (source === void 0 || source === null) return collection;
|
|
27388
28190
|
const iterator = getSandboxIterator(source, budget, context);
|
|
@@ -27390,7 +28192,14 @@ function populateCollection(source, collection, { name, budget, context, append,
|
|
|
27390
28192
|
let entry;
|
|
27391
28193
|
let failure;
|
|
27392
28194
|
const retained = {};
|
|
27393
|
-
budget.setRetainedValues(retained, () => [
|
|
28195
|
+
budget.setRetainedValues(retained, () => [
|
|
28196
|
+
source,
|
|
28197
|
+
iterator.retainedValue,
|
|
28198
|
+
collection,
|
|
28199
|
+
entry,
|
|
28200
|
+
failure,
|
|
28201
|
+
...retainedValues?.() ?? []
|
|
28202
|
+
]);
|
|
27394
28203
|
const checkData = createDataCheckpoint(budget, context);
|
|
27395
28204
|
const closeOnThrow = (error) => {
|
|
27396
28205
|
failure = isCapturedException(error) ? error.reason : error;
|
|
@@ -27400,21 +28209,29 @@ function populateCollection(source, collection, { name, budget, context, append,
|
|
|
27400
28209
|
};
|
|
27401
28210
|
try {
|
|
27402
28211
|
const closing = iterator.return?.();
|
|
27403
|
-
if (iterator.generator || iterator.asynchronous)
|
|
27404
|
-
|
|
27405
|
-
|
|
28212
|
+
if (iterator.generator || iterator.asynchronous)
|
|
28213
|
+
return Promise.resolve(closing).then(() => {
|
|
28214
|
+
throw error;
|
|
28215
|
+
}, rethrow);
|
|
27406
28216
|
} catch (closeError) {
|
|
27407
28217
|
return rethrow(closeError);
|
|
27408
28218
|
}
|
|
27409
28219
|
throw error;
|
|
27410
28220
|
};
|
|
27411
28221
|
const consume = (result) => {
|
|
27412
|
-
if (typeof result !== "object" || result === null)
|
|
28222
|
+
if (typeof result !== "object" || result === null)
|
|
28223
|
+
throw new TypeError("Iterator result must be an object.");
|
|
27413
28224
|
if (result.done) return true;
|
|
27414
28225
|
entry = result.value;
|
|
27415
28226
|
try {
|
|
27416
28227
|
budget.visitNode();
|
|
27417
28228
|
const growth = append(entry);
|
|
28229
|
+
if (growth instanceof Promise)
|
|
28230
|
+
return growth.then((size) => {
|
|
28231
|
+
entry = void 0;
|
|
28232
|
+
checkData(collection, size);
|
|
28233
|
+
return false;
|
|
28234
|
+
}).catch(closeOnThrow);
|
|
27418
28235
|
entry = void 0;
|
|
27419
28236
|
checkData(collection, growth);
|
|
27420
28237
|
} catch (error) {
|
|
@@ -27422,7 +28239,7 @@ function populateCollection(source, collection, { name, budget, context, append,
|
|
|
27422
28239
|
}
|
|
27423
28240
|
return false;
|
|
27424
28241
|
};
|
|
27425
|
-
if (iterator.generator || iterator.asynchronous) {
|
|
28242
|
+
if (iterator.generator || iterator.asynchronous || context !== void 0) {
|
|
27426
28243
|
return (async () => {
|
|
27427
28244
|
try {
|
|
27428
28245
|
checkData(collection, 0, true);
|
|
@@ -28146,7 +28963,11 @@ async function evaluateObjectExpression(node, context) {
|
|
|
28146
28963
|
const releaseKey = retainValues(context.budget, () => [key.value]);
|
|
28147
28964
|
let value;
|
|
28148
28965
|
try {
|
|
28149
|
-
value = await evaluateNode(property.value, {
|
|
28966
|
+
value = await evaluateNode(property.value, {
|
|
28967
|
+
...context,
|
|
28968
|
+
inferredName: String(key.value),
|
|
28969
|
+
...property.value.type === "FunctionExpression" && property.value.method === true ? { functionEnvironment: { homeObject: object } } : {}
|
|
28970
|
+
});
|
|
28150
28971
|
} finally {
|
|
28151
28972
|
releaseKey();
|
|
28152
28973
|
}
|
|
@@ -28171,7 +28992,7 @@ async function evaluateObjectExpression(node, context) {
|
|
|
28171
28992
|
}
|
|
28172
28993
|
}
|
|
28173
28994
|
function isObjectPrototypeSetterProperty(property, key) {
|
|
28174
|
-
return !property.computed && !property.shorthand && key === "__proto__";
|
|
28995
|
+
return !property.computed && !property.shorthand && key === "__proto__" && !(property.value.type === "FunctionExpression" && property.value.method === true);
|
|
28175
28996
|
}
|
|
28176
28997
|
async function evaluateTemplateLiteral(node, context) {
|
|
28177
28998
|
let value = context.budget.allocateString(node.quasis[0]?.value.cooked ?? "");
|
|
@@ -28226,7 +29047,8 @@ async function evaluateTaggedTemplateExpression(node, context) {
|
|
|
28226
29047
|
if (node.tag.type === "MemberExpression") return evaluateMemberAccess(node.tag, context, async (member) => {
|
|
28227
29048
|
if (member.kind === "nullish") throw new TypeError("Tagged template tag must be a function.");
|
|
28228
29049
|
const key = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
28229
|
-
|
|
29050
|
+
const receiver = member.superReceiver === void 0 ? member.object : member.superReceiver.value;
|
|
29051
|
+
return invokeTag(await getPropertyValue(member.object, key, context, receiver), receiver);
|
|
28230
29052
|
});
|
|
28231
29053
|
const tag = await evaluateNode(node.tag, context);
|
|
28232
29054
|
return tag.kind === "normal" ? invokeTag(tag.value, void 0) : tag;
|
|
@@ -28321,7 +29143,8 @@ async function evaluateBinaryExpression(node, context) {
|
|
|
28321
29143
|
if (isSandboxBox(rightValue) && (!equality || left.value !== null && left.value !== void 0 && typeof left.value !== "object"))
|
|
28322
29144
|
rightValue = await toNumericPrimitive(rightValue, context);
|
|
28323
29145
|
}
|
|
28324
|
-
const
|
|
29146
|
+
const operation = applyBinaryOperator(node, leftValue, rightValue, context);
|
|
29147
|
+
const value = operation instanceof Promise ? await operation : operation;
|
|
28325
29148
|
return {
|
|
28326
29149
|
kind: "normal",
|
|
28327
29150
|
hasValue: true,
|
|
@@ -28412,8 +29235,17 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
28412
29235
|
if (member.object === null || member.object === void 0) {
|
|
28413
29236
|
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
28414
29237
|
}
|
|
28415
|
-
property = await toPropertyKey(
|
|
28416
|
-
|
|
29238
|
+
property = await toPropertyKey(
|
|
29239
|
+
member.property,
|
|
29240
|
+
context.budget,
|
|
29241
|
+
createCoercionContext(context)
|
|
29242
|
+
);
|
|
29243
|
+
current = await getPropertyValue(
|
|
29244
|
+
member.object,
|
|
29245
|
+
property,
|
|
29246
|
+
context,
|
|
29247
|
+
member.superReceiver === void 0 ? member.object : member.superReceiver.value
|
|
29248
|
+
);
|
|
28417
29249
|
}
|
|
28418
29250
|
if (node.operator === "&&=" && !isTruthy(current)) {
|
|
28419
29251
|
return {
|
|
@@ -28449,9 +29281,22 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
28449
29281
|
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
28450
29282
|
}
|
|
28451
29283
|
operands = [value];
|
|
28452
|
-
property ??= await toPropertyKey(
|
|
28453
|
-
|
|
28454
|
-
|
|
29284
|
+
property ??= await toPropertyKey(
|
|
29285
|
+
member.property,
|
|
29286
|
+
context.budget,
|
|
29287
|
+
createCoercionContext(context)
|
|
29288
|
+
);
|
|
29289
|
+
if (member.superReceiver === void 0)
|
|
29290
|
+
await setSandboxProperty(
|
|
29291
|
+
member.object,
|
|
29292
|
+
property,
|
|
29293
|
+
value,
|
|
29294
|
+
context.budget,
|
|
29295
|
+
true,
|
|
29296
|
+
createCoercionContext(context)
|
|
29297
|
+
);
|
|
29298
|
+
else
|
|
29299
|
+
await setSuperProperty(member.object, member.superReceiver.value, property, value, context);
|
|
28455
29300
|
return {
|
|
28456
29301
|
kind: "normal",
|
|
28457
29302
|
hasValue: true,
|
|
@@ -29526,11 +30371,11 @@ async function evaluateMemberUpdateExpression(node, context) {
|
|
|
29526
30371
|
}
|
|
29527
30372
|
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
29528
30373
|
const current = toNumber(
|
|
29529
|
-
await toNumericPrimitive(getPropertyValue(member.object, property, context), context)
|
|
30374
|
+
await toNumericPrimitive(await getPropertyValue(member.object, property, context, member.superReceiver === void 0 ? member.object : member.superReceiver.value), context)
|
|
29530
30375
|
);
|
|
29531
30376
|
const next = node.operator === "++" ? current + 1 : current - 1;
|
|
29532
|
-
if (member.superReceiver === void 0) setSandboxProperty(member.object, property, next, context.budget);
|
|
29533
|
-
else setSuperProperty(member.object, member.superReceiver.value, property, next, context
|
|
30377
|
+
if (member.superReceiver === void 0) await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
|
|
30378
|
+
else await setSuperProperty(member.object, member.superReceiver.value, property, next, context);
|
|
29534
30379
|
return {
|
|
29535
30380
|
kind: "normal",
|
|
29536
30381
|
hasValue: true,
|
|
@@ -29547,28 +30392,38 @@ async function evaluateMemberExpression(node, context) {
|
|
|
29547
30392
|
return {
|
|
29548
30393
|
kind: "normal",
|
|
29549
30394
|
hasValue: true,
|
|
29550
|
-
value:
|
|
30395
|
+
value: await getPropertyValue(
|
|
30396
|
+
member.object,
|
|
30397
|
+
await toPropertyKey(member.property, context.budget, createCoercionContext(context)),
|
|
30398
|
+
context,
|
|
30399
|
+
member.superReceiver === void 0 ? member.object : member.superReceiver.value
|
|
30400
|
+
)
|
|
29551
30401
|
};
|
|
29552
30402
|
});
|
|
29553
30403
|
}
|
|
29554
|
-
function getPropertyValue(target, property, context) {
|
|
30404
|
+
function getPropertyValue(target, property, context, receiver = target) {
|
|
29555
30405
|
if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
|
|
30406
|
+
const descriptor = getSandboxPropertyDescriptor(target, property, context.budget);
|
|
30407
|
+
if (descriptor !== void 0)
|
|
30408
|
+
return readPropertyDescriptor(descriptor, receiver, createCoercionContext(context), true);
|
|
29556
30409
|
if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
|
|
29557
30410
|
const prototype = getBoxedPrototype(target, context.budget);
|
|
29558
30411
|
if (prototype !== void 0) {
|
|
29559
30412
|
if (typeof target === "string" && (property === "length" || getStringIndex(property) !== void 0))
|
|
29560
30413
|
return getStringMember(target, property, context.budget);
|
|
29561
|
-
return
|
|
30414
|
+
return getPropertyValue(prototype, property, context, receiver);
|
|
29562
30415
|
}
|
|
29563
30416
|
}
|
|
29564
30417
|
if (typeof target === "string") return getStringMember(target, property, context.budget);
|
|
29565
30418
|
if (typeof target === "number") return getNumberMember(property, context.budget);
|
|
29566
30419
|
if (typeof target === "boolean") return void 0;
|
|
29567
30420
|
if (isFloat32Array(target)) return getFloat32Member(target, property, context.budget);
|
|
29568
|
-
if (isSandboxDate(target))
|
|
30421
|
+
if (isSandboxDate(target))
|
|
30422
|
+
return getDateMember(property, context.budget, context.compilation?.owner);
|
|
29569
30423
|
if (isSandboxMap(target)) return getMapMember(target, property, createMapMethodOptions(context));
|
|
29570
30424
|
if (isSandboxSet(target)) return getSetMember(target, property, createSetMethodOptions(context));
|
|
29571
|
-
if (isSandboxCollectionIterator(target))
|
|
30425
|
+
if (isSandboxCollectionIterator(target))
|
|
30426
|
+
return getCollectionIteratorMember(target, property, context.budget);
|
|
29572
30427
|
if (isSandboxGenerator(target)) return getGeneratorMember(target, property, context.budget);
|
|
29573
30428
|
if (isSandboxClosure(target)) return getClosureMemberValue(target, property, context);
|
|
29574
30429
|
if (isSandboxPromise(target)) return getPromiseMember(property, context.budget);
|
|
@@ -29585,13 +30440,21 @@ function createPatternContext(context, scope = context.scope, evaluate = evaluat
|
|
|
29585
30440
|
evaluate: (node, inferredName) => evaluate(node, { ...evaluationContext, inferredName }),
|
|
29586
30441
|
toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
|
|
29587
30442
|
getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
|
|
29588
|
-
setProperty: (target, key, value) => setSandboxProperty(
|
|
30443
|
+
setProperty: (target, key, value) => setSandboxProperty(
|
|
30444
|
+
target,
|
|
30445
|
+
key,
|
|
30446
|
+
value,
|
|
30447
|
+
context.budget,
|
|
30448
|
+
true,
|
|
30449
|
+
createCoercionContext(evaluationContext)
|
|
30450
|
+
)
|
|
29589
30451
|
};
|
|
29590
30452
|
}
|
|
29591
30453
|
async function evaluateCallExpression(node, context) {
|
|
29592
30454
|
if (node.callee.type === "Super") {
|
|
29593
30455
|
const construction = context.functionEnvironment?.construction;
|
|
29594
|
-
if (construction === void 0)
|
|
30456
|
+
if (construction === void 0)
|
|
30457
|
+
throw new ReferenceError("Super constructor binding is unavailable.");
|
|
29595
30458
|
const args = await evaluateCallArguments(node.arguments, context);
|
|
29596
30459
|
if (!args.ok) return args.result;
|
|
29597
30460
|
return { kind: "normal", hasValue: true, value: await construction.superCall(args.value) };
|
|
@@ -29746,7 +30609,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
29746
30609
|
property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
|
|
29747
30610
|
};
|
|
29748
30611
|
if (member.superReceiver !== void 0)
|
|
29749
|
-
return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.superReceiver.value);
|
|
30612
|
+
return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context, member.superReceiver.value), context, member.superReceiver.value);
|
|
29750
30613
|
if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") && getBoxedPrototype(member.object, context.budget) !== void 0) {
|
|
29751
30614
|
if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
|
|
29752
30615
|
if (typeof member.object === "string" && isStringMethodName(member.property))
|
|
@@ -29754,7 +30617,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
29754
30617
|
if (typeof member.object === "number" && isNumberMethodName(member.property))
|
|
29755
30618
|
return evaluateNumberMethodCall(node, member.object, member.property, context);
|
|
29756
30619
|
}
|
|
29757
|
-
return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
|
|
30620
|
+
return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
|
|
29758
30621
|
}
|
|
29759
30622
|
if (typeof member.object === "string" && isStringMethodName(member.property)) {
|
|
29760
30623
|
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
@@ -29835,7 +30698,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
29835
30698
|
return evaluateResolvedCallExpression(node, memberValue, context, member.object);
|
|
29836
30699
|
}
|
|
29837
30700
|
if (isSandboxClosure(member.object)) {
|
|
29838
|
-
const memberValue =
|
|
30701
|
+
const memberValue = await getPropertyValue(member.object, member.property, context);
|
|
29839
30702
|
if (memberValue === void 0) {
|
|
29840
30703
|
throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
|
|
29841
30704
|
}
|
|
@@ -29862,7 +30725,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
29862
30725
|
}
|
|
29863
30726
|
return evaluateResolvedCallExpression(
|
|
29864
30727
|
node,
|
|
29865
|
-
|
|
30728
|
+
await getPropertyValue(member.object, member.property, context),
|
|
29866
30729
|
context,
|
|
29867
30730
|
member.object
|
|
29868
30731
|
);
|
|
@@ -30064,7 +30927,8 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
30064
30927
|
return true;
|
|
30065
30928
|
}
|
|
30066
30929
|
if (isFloat32ArrayConstructor(right)) return isFloat32Array(left);
|
|
30067
|
-
if (isDateConstructor(right))
|
|
30930
|
+
if (isDateConstructor(right))
|
|
30931
|
+
return isSandboxDate(left) && getDatePrototype(left, context.budget, context.compilation?.owner) !== null;
|
|
30068
30932
|
if (isSandboxSetConstructor(right) && isSandboxSet(left)) {
|
|
30069
30933
|
return true;
|
|
30070
30934
|
}
|
|
@@ -30073,16 +30937,20 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
30073
30937
|
}
|
|
30074
30938
|
if (isGuestClosure(right)) {
|
|
30075
30939
|
if (typeof left !== "object" || left === null) return false;
|
|
30076
|
-
const
|
|
30077
|
-
|
|
30078
|
-
|
|
30079
|
-
|
|
30080
|
-
|
|
30081
|
-
|
|
30082
|
-
|
|
30083
|
-
|
|
30084
|
-
|
|
30085
|
-
|
|
30940
|
+
const check = (prototype2) => {
|
|
30941
|
+
if (typeof prototype2 !== "object" || prototype2 === null) {
|
|
30942
|
+
throw new TypeError("Function has a non-object prototype in instanceof check.");
|
|
30943
|
+
}
|
|
30944
|
+
let depth = 0;
|
|
30945
|
+
for (let current = getSandboxPrototype(left, context.budget); current !== null; current = getSandboxPrototype(current, context.budget)) {
|
|
30946
|
+
context.budget.visitNode();
|
|
30947
|
+
assertSandboxDataDepth(depth++);
|
|
30948
|
+
if (current === prototype2) return true;
|
|
30949
|
+
}
|
|
30950
|
+
return false;
|
|
30951
|
+
};
|
|
30952
|
+
const prototype = getPropertyValue(right, "prototype", context);
|
|
30953
|
+
return prototype instanceof Promise ? prototype.then(check) : check(prototype);
|
|
30086
30954
|
}
|
|
30087
30955
|
return false;
|
|
30088
30956
|
case "in":
|
|
@@ -30253,7 +31121,7 @@ async function toNumericPrimitive(value, context) {
|
|
|
30253
31121
|
}
|
|
30254
31122
|
if (isIndexableSandboxValue(value)) {
|
|
30255
31123
|
for (const methodName of ["valueOf", "toString"]) {
|
|
30256
|
-
const method =
|
|
31124
|
+
const method = await getPropertyValue(value, methodName, context);
|
|
30257
31125
|
if (methodName === "toString" && method === void 0 && !Object.hasOwn(value, methodName)) {
|
|
30258
31126
|
return toString(value);
|
|
30259
31127
|
}
|
|
@@ -30341,13 +31209,18 @@ function getArrayMemberValue(target, property, context) {
|
|
|
30341
31209
|
}
|
|
30342
31210
|
return getArrayMember(target, property, createArrayMethodOptions(context));
|
|
30343
31211
|
}
|
|
30344
|
-
function setSandboxProperty(target, property, value, budget, checkInherited = true) {
|
|
31212
|
+
function setSandboxProperty(target, property, value, budget, checkInherited = true, context) {
|
|
30345
31213
|
if (isSandboxDate(target)) throw new TypeError("Date own properties are not supported.");
|
|
30346
31214
|
if (isGuestHostObject(target)) {
|
|
30347
31215
|
setHostObjectMember(target, String(property), value);
|
|
30348
31216
|
return;
|
|
30349
31217
|
}
|
|
30350
31218
|
const prototypeOwner = target;
|
|
31219
|
+
if (checkInherited) {
|
|
31220
|
+
const descriptor2 = getSandboxPropertyDescriptor(target, property, budget);
|
|
31221
|
+
if (descriptor2 !== void 0 && !("value" in descriptor2))
|
|
31222
|
+
return writePropertyDescriptor(descriptor2, target, value, context);
|
|
31223
|
+
}
|
|
30351
31224
|
if (isGuestClosure(target)) target = materializeFunctionProperties(target);
|
|
30352
31225
|
if (isFloat32Array(target)) {
|
|
30353
31226
|
setFloat32Member(target, property, value);
|
|
@@ -30383,15 +31256,18 @@ function setSandboxProperty(target, property, value, budget, checkInherited = tr
|
|
|
30383
31256
|
const properties = isSandboxClosure(prototype) ? prototype.properties : prototype;
|
|
30384
31257
|
const inherited = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
|
|
30385
31258
|
if (inherited === void 0) continue;
|
|
30386
|
-
if (inherited.writable !== true)
|
|
31259
|
+
if (inherited.writable !== true)
|
|
31260
|
+
throw new TypeError(`Cannot assign to read only property '${key}'.`);
|
|
30387
31261
|
break;
|
|
30388
31262
|
}
|
|
30389
31263
|
}
|
|
30390
31264
|
defineSandboxProperty(target, key, value);
|
|
30391
31265
|
}
|
|
30392
31266
|
}
|
|
30393
|
-
function setSuperProperty(base, receiver, key, value,
|
|
30394
|
-
|
|
31267
|
+
function setSuperProperty(base, receiver, key, value, context) {
|
|
31268
|
+
const budget = context.budget;
|
|
31269
|
+
if (typeof base !== "object" || base === null)
|
|
31270
|
+
throw new TypeError("Cannot assign a property of null.");
|
|
30395
31271
|
let depth = 0;
|
|
30396
31272
|
for (let current = base; current !== null; current = getSandboxPrototype(current, budget)) {
|
|
30397
31273
|
budget.visitNode();
|
|
@@ -30399,11 +31275,15 @@ function setSuperProperty(base, receiver, key, value, budget) {
|
|
|
30399
31275
|
const properties = isSandboxClosure(current) ? current.properties : current;
|
|
30400
31276
|
const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
|
|
30401
31277
|
if (descriptor === void 0) continue;
|
|
30402
|
-
if (
|
|
31278
|
+
if (!("value" in descriptor))
|
|
31279
|
+
return writePropertyDescriptor(descriptor, receiver, value, createCoercionContext(context));
|
|
31280
|
+
if (descriptor.writable !== true)
|
|
31281
|
+
throw new TypeError(`Cannot assign to read only property '${key}'.`);
|
|
30403
31282
|
break;
|
|
30404
31283
|
}
|
|
30405
|
-
if (typeof receiver !== "object" || receiver === null)
|
|
30406
|
-
|
|
31284
|
+
if (typeof receiver !== "object" || receiver === null)
|
|
31285
|
+
throw new TypeError("Super assignment requires an object receiver.");
|
|
31286
|
+
return setSandboxProperty(receiver, key, value, budget, false);
|
|
30407
31287
|
}
|
|
30408
31288
|
function deleteSandboxProperty(target, property) {
|
|
30409
31289
|
if (isGuestHostObject(target)) return deleteHostObjectMember(target, String(property));
|
|
@@ -30467,7 +31347,7 @@ function createArrayMethodOptions(context) {
|
|
|
30467
31347
|
budget: context.budget,
|
|
30468
31348
|
context: createCoercionContext(context),
|
|
30469
31349
|
hasProperty: (value, property) => hasSandboxProperty(value, property, context),
|
|
30470
|
-
setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
|
|
31350
|
+
setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget, true, createCoercionContext(context)),
|
|
30471
31351
|
deleteProperty: deleteSandboxProperty,
|
|
30472
31352
|
callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, void 0, thisValue)
|
|
30473
31353
|
};
|
|
@@ -30605,11 +31485,12 @@ async function evaluateObjectSpread(node, context) {
|
|
|
30605
31485
|
};
|
|
30606
31486
|
}
|
|
30607
31487
|
if (isGuestHostObject(value.value)) {
|
|
30608
|
-
const
|
|
31488
|
+
const entries2 = [];
|
|
30609
31489
|
for (const key of getHostObjectKeys(value.value)) {
|
|
30610
|
-
if (hasHostObjectMember(value.value, key, true))
|
|
31490
|
+
if (hasHostObjectMember(value.value, key, true))
|
|
31491
|
+
entries2.push([key, getHostObjectMember(value.value, key)]);
|
|
30611
31492
|
}
|
|
30612
|
-
return { ok: true, value:
|
|
31493
|
+
return { ok: true, value: entries2 };
|
|
30613
31494
|
}
|
|
30614
31495
|
if (isSandboxClosure(value.value) && !isGuestClosure(value.value) || isSandboxPromise(value.value)) {
|
|
30615
31496
|
throw new TypeError(
|
|
@@ -30619,10 +31500,17 @@ async function evaluateObjectSpread(node, context) {
|
|
|
30619
31500
|
const spreadValue = isGuestClosure(value.value) ? value.value.properties ?? {} : Object(value.value);
|
|
30620
31501
|
const keys = Object.keys(spreadValue);
|
|
30621
31502
|
context.budget.allocateArrayLength(keys.length);
|
|
30622
|
-
|
|
30623
|
-
|
|
30624
|
-
|
|
30625
|
-
|
|
31503
|
+
const entries = [];
|
|
31504
|
+
const release = retainValues(context.budget, () => [value.value, entries]);
|
|
31505
|
+
try {
|
|
31506
|
+
for (const key of keys) {
|
|
31507
|
+
if (!hasOwnSandboxProperty(value.value, key, true)) continue;
|
|
31508
|
+
entries.push([key, await getPropertyValue(value.value, key, context)]);
|
|
31509
|
+
}
|
|
31510
|
+
return { ok: true, value: entries };
|
|
31511
|
+
} finally {
|
|
31512
|
+
release();
|
|
31513
|
+
}
|
|
30626
31514
|
}
|
|
30627
31515
|
function describeObjectSpreadValue(value) {
|
|
30628
31516
|
if (value === null) {
|
|
@@ -30689,7 +31577,12 @@ async function evaluateFunctionExpression(node, context, evaluateNode2) {
|
|
|
30689
31577
|
return {
|
|
30690
31578
|
kind: "normal",
|
|
30691
31579
|
hasValue: true,
|
|
30692
|
-
value: createInterpretedClosure(
|
|
31580
|
+
value: createInterpretedClosure(
|
|
31581
|
+
node,
|
|
31582
|
+
context,
|
|
31583
|
+
evaluateNode2,
|
|
31584
|
+
node.method === true ? context.functionEnvironment?.homeObject : void 0
|
|
31585
|
+
)
|
|
30693
31586
|
};
|
|
30694
31587
|
}
|
|
30695
31588
|
const wrapperScope = context.scope.child();
|
|
@@ -30771,7 +31664,7 @@ function executeAsyncFunction(execute, budget, signal) {
|
|
|
30771
31664
|
try {
|
|
30772
31665
|
const value = await execute(completePrefix);
|
|
30773
31666
|
resolve(
|
|
30774
|
-
|
|
31667
|
+
requiresPromiseResolution(value, budget) ? awaitSandboxValue(
|
|
30775
31668
|
createSandboxPromise(resolveSandboxValue(value, { budget }), {
|
|
30776
31669
|
trackReplay: false
|
|
30777
31670
|
}),
|
|
@@ -32197,19 +33090,29 @@ async function stringifyJson(value, replacer, indent, budget, context) {
|
|
|
32197
33090
|
return budget.allocateString(output);
|
|
32198
33091
|
}
|
|
32199
33092
|
async function stringifyProperty(key, holder, state, indent = "") {
|
|
32200
|
-
let value =
|
|
32201
|
-
|
|
32202
|
-
|
|
32203
|
-
|
|
32204
|
-
|
|
32205
|
-
if (
|
|
32206
|
-
|
|
33093
|
+
let value = await getStringifyProperty(holder, key, state);
|
|
33094
|
+
const release = retainValues(state.budget, () => [holder, value]);
|
|
33095
|
+
try {
|
|
33096
|
+
if (isSandboxDate(value)) {
|
|
33097
|
+
value = dateMethods.get("toJSON").invoke(value, []);
|
|
33098
|
+
} else if (isStringifyContainer(value)) {
|
|
33099
|
+
const toJSON = await getStringifyProperty(value, "toJSON", state);
|
|
33100
|
+
if (isSandboxClosure(toJSON)) {
|
|
33101
|
+
value = await callStringifyClosure(toJSON, [key], value, state);
|
|
33102
|
+
}
|
|
33103
|
+
}
|
|
33104
|
+
if (state.replacer !== void 0) {
|
|
33105
|
+
value = await callStringifyClosure(
|
|
33106
|
+
state.replacer,
|
|
33107
|
+
[key, toSandboxValue(value)],
|
|
33108
|
+
holder,
|
|
33109
|
+
state
|
|
33110
|
+
);
|
|
32207
33111
|
}
|
|
33112
|
+
return await stringifyValue(value, state, indent);
|
|
33113
|
+
} finally {
|
|
33114
|
+
release();
|
|
32208
33115
|
}
|
|
32209
|
-
if (state.replacer !== void 0) {
|
|
32210
|
-
value = await callStringifyClosure(state.replacer, [key, toSandboxValue(value)], holder, state);
|
|
32211
|
-
}
|
|
32212
|
-
return stringifyValue(value, state, indent);
|
|
32213
33116
|
}
|
|
32214
33117
|
async function stringifyValue(value, state, indent) {
|
|
32215
33118
|
if (isSandboxBox(value)) {
|
|
@@ -32245,10 +33148,12 @@ async function stringifyValue(value, state, indent) {
|
|
|
32245
33148
|
}
|
|
32246
33149
|
async function stringifyArray(value, state, indent) {
|
|
32247
33150
|
enterStringifyObject(value, state);
|
|
33151
|
+
const entries = [];
|
|
33152
|
+
const release = retainValues(state.budget, () => entries);
|
|
32248
33153
|
try {
|
|
32249
33154
|
const nextIndent = indent + state.gap;
|
|
32250
|
-
const
|
|
32251
|
-
for (let index = 0; index <
|
|
33155
|
+
const length = value.length;
|
|
33156
|
+
for (let index = 0; index < length; index += 1) {
|
|
32252
33157
|
entries.push(await stringifyProperty(String(index), value, state, nextIndent) ?? "null");
|
|
32253
33158
|
}
|
|
32254
33159
|
if (entries.length === 0) {
|
|
@@ -32262,14 +33167,16 @@ ${nextIndent}${entries.join(`,
|
|
|
32262
33167
|
${nextIndent}`)}
|
|
32263
33168
|
${indent}]`;
|
|
32264
33169
|
} finally {
|
|
33170
|
+
release();
|
|
32265
33171
|
leaveStringifyObject(value, state);
|
|
32266
33172
|
}
|
|
32267
33173
|
}
|
|
32268
33174
|
async function stringifyObject(value, state, indent) {
|
|
32269
33175
|
enterStringifyObject(value, state);
|
|
33176
|
+
const entries = [];
|
|
33177
|
+
const release = retainValues(state.budget, () => entries);
|
|
32270
33178
|
try {
|
|
32271
33179
|
const nextIndent = indent + state.gap;
|
|
32272
|
-
const entries = [];
|
|
32273
33180
|
for (const key of Object.keys(value)) {
|
|
32274
33181
|
const serialized = await stringifyProperty(key, value, state, nextIndent);
|
|
32275
33182
|
if (serialized !== void 0) {
|
|
@@ -32287,6 +33194,7 @@ ${nextIndent}${entries.join(`,
|
|
|
32287
33194
|
${nextIndent}`)}
|
|
32288
33195
|
${indent}}`;
|
|
32289
33196
|
} finally {
|
|
33197
|
+
release();
|
|
32290
33198
|
leaveStringifyObject(value, state);
|
|
32291
33199
|
}
|
|
32292
33200
|
}
|
|
@@ -32342,15 +33250,10 @@ function toSandboxValue(value) {
|
|
|
32342
33250
|
`JSON.stringify(value) produced an unsupported value of type ${typeof value}.`
|
|
32343
33251
|
);
|
|
32344
33252
|
}
|
|
32345
|
-
function
|
|
32346
|
-
|
|
32347
|
-
|
|
32348
|
-
|
|
32349
|
-
}
|
|
32350
|
-
if ("get" in descriptor || "set" in descriptor) {
|
|
32351
|
-
throw new TypeError(`JSON.stringify(value) cannot serialize accessor property ${key}.`);
|
|
32352
|
-
}
|
|
32353
|
-
return descriptor.value;
|
|
33253
|
+
function getStringifyProperty(target, key, state) {
|
|
33254
|
+
if (state.context?.getProperty !== void 0) return state.context.getProperty(target, key);
|
|
33255
|
+
const descriptor = getSandboxPropertyDescriptor(target, key, state.budget);
|
|
33256
|
+
return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, target, state.context);
|
|
32354
33257
|
}
|
|
32355
33258
|
function copyJsonToSandbox(value, budget) {
|
|
32356
33259
|
if (value === null || value === void 0 || typeof value === "boolean" || typeof value === "number") {
|
|
@@ -34608,4 +35511,4 @@ export {
|
|
|
34608
35511
|
FileSnapshotBackend,
|
|
34609
35512
|
run
|
|
34610
35513
|
};
|
|
34611
|
-
//# sourceMappingURL=chunk-
|
|
35514
|
+
//# sourceMappingURL=chunk-YKISHTWT.js.map
|