poe-code 14.0.62 → 14.0.64
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 +977 -528
- 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-F7TJSPDZ.js → chunk-3EXDJDQM.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-VKGWGZBH.js → chunk-XO7B4P27.js} +945 -545
- package/packages/safe-js/dist/chunks/chunk-XO7B4P27.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/graph-depth.js +3 -0
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/interp/boxed.d.ts +14 -0
- package/packages/safe-js/dist/interp/boxed.js +50 -0
- package/packages/safe-js/dist/interp/globals/collections.js +4 -4
- package/packages/safe-js/dist/interp/globals/console-json.js +15 -18
- package/packages/safe-js/dist/interp/globals/misc.js +1 -1
- package/packages/safe-js/dist/interp/globals/object-array.js +19 -14
- package/packages/safe-js/dist/interp/globals/object.js +10 -5
- package/packages/safe-js/dist/interp/globals/primitives.d.ts +8 -0
- package/packages/safe-js/dist/interp/globals/primitives.js +69 -0
- package/packages/safe-js/dist/interp/host-bridge.js +22 -0
- package/packages/safe-js/dist/interp/interpreter.js +175 -122
- package/packages/safe-js/dist/interp/iteration.d.ts +5 -3
- package/packages/safe-js/dist/interp/iteration.js +22 -1
- package/packages/safe-js/dist/interp/methods/array.js +6 -3
- package/packages/safe-js/dist/interp/methods/function.js +32 -15
- package/packages/safe-js/dist/interp/methods/number.d.ts +1 -0
- package/packages/safe-js/dist/interp/methods/number.js +4 -1
- package/packages/safe-js/dist/interp/methods/string.d.ts +2 -0
- package/packages/safe-js/dist/interp/methods/string.js +2 -2
- package/packages/safe-js/dist/interp/object-model.d.ts +5 -0
- package/packages/safe-js/dist/interp/object-model.js +66 -14
- package/packages/safe-js/dist/interp/promise.js +68 -61
- package/packages/safe-js/dist/interp/string-coercion.js +4 -1
- package/packages/safe-js/dist/interp/values.d.ts +1 -0
- package/packages/safe-js/dist/interp/values.js +78 -3
- package/packages/safe-js/dist/migrate.d.ts +2 -2
- package/packages/safe-js/dist/migration-file.d.ts +4 -4
- package/packages/safe-js/dist/snapshot/boxed.d.ts +16 -0
- package/packages/safe-js/dist/snapshot/boxed.js +52 -0
- package/packages/safe-js/dist/snapshot/dump-format.js +18 -5
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +5 -0
- package/packages/safe-js/dist/snapshot/replay-data.js +24 -0
- package/packages/safe-js/dist/snapshot/restore.js +8 -0
- package/packages/safe-js/dist/snapshot/serialize.d.ts +4 -2
- package/packages/safe-js/dist/snapshot/serialize.js +18 -10
- package/packages/safe-js/dist/snapshot/validation.js +22 -1
- package/packages/safe-js/dist/chunks/chunk-VKGWGZBH.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-F7TJSPDZ.js.map → chunk-3EXDJDQM.js.map} +0 -0
|
@@ -6448,8 +6448,50 @@ function nativeIterator(collection, method) {
|
|
|
6448
6448
|
return collection.kind === "map" ? collection.entries[method]() : collection.values[method]();
|
|
6449
6449
|
}
|
|
6450
6450
|
|
|
6451
|
-
// packages/safe-js/src/interp/
|
|
6451
|
+
// packages/safe-js/src/interp/boxed.ts
|
|
6452
6452
|
import { types as types3 } from "node:util";
|
|
6453
|
+
var boxes = /* @__PURE__ */ new WeakSet();
|
|
6454
|
+
var numberValue = Number.prototype.valueOf;
|
|
6455
|
+
var stringValue = String.prototype.valueOf;
|
|
6456
|
+
var booleanValue = Boolean.prototype.valueOf;
|
|
6457
|
+
function nativeBoxedValue(value) {
|
|
6458
|
+
if (types3.isNumberObject(value)) return Reflect.apply(numberValue, value, []);
|
|
6459
|
+
if (types3.isStringObject(value)) return Reflect.apply(stringValue, value, []);
|
|
6460
|
+
if (types3.isBooleanObject(value)) return Reflect.apply(booleanValue, value, []);
|
|
6461
|
+
return void 0;
|
|
6462
|
+
}
|
|
6463
|
+
function createSandboxBox(value) {
|
|
6464
|
+
if (typeof value !== "number" && typeof value !== "string" && typeof value !== "boolean")
|
|
6465
|
+
throw new TypeError("Invalid boxed primitive payload.");
|
|
6466
|
+
const box = Object(value);
|
|
6467
|
+
Object.setPrototypeOf(box, null);
|
|
6468
|
+
boxes.add(box);
|
|
6469
|
+
return box;
|
|
6470
|
+
}
|
|
6471
|
+
function isSandboxBox(value) {
|
|
6472
|
+
return typeof value === "object" && value !== null && boxes.has(value);
|
|
6473
|
+
}
|
|
6474
|
+
function boxedValue(value) {
|
|
6475
|
+
if (!boxes.has(value)) throw new TypeError("Expected a sandbox boxed primitive.");
|
|
6476
|
+
return nativeBoxedValue(value);
|
|
6477
|
+
}
|
|
6478
|
+
function primitiveReceiver(value, kind) {
|
|
6479
|
+
const primitive = isSandboxBox(value) ? boxedValue(value) : value;
|
|
6480
|
+
if (typeof primitive !== kind) throw new TypeError(`${kind} method requires a ${kind} receiver.`);
|
|
6481
|
+
return primitive;
|
|
6482
|
+
}
|
|
6483
|
+
function boxedDataProperties(value) {
|
|
6484
|
+
const primitive = nativeBoxedValue(value);
|
|
6485
|
+
return Object.entries(Object.getOwnPropertyDescriptors(value)).filter(([key]) => {
|
|
6486
|
+
if (typeof primitive !== "string") return true;
|
|
6487
|
+
if (key === "length") return false;
|
|
6488
|
+
const index = Number(key);
|
|
6489
|
+
return !(Number.isInteger(index) && index >= 0 && index < primitive.length && String(index) === key);
|
|
6490
|
+
});
|
|
6491
|
+
}
|
|
6492
|
+
|
|
6493
|
+
// packages/safe-js/src/interp/host-capabilities.ts
|
|
6494
|
+
import { types as types4 } from "node:util";
|
|
6453
6495
|
var MAX_INDEXED_LENGTH = 65536;
|
|
6454
6496
|
var MAX_NAMED_KEYS = 65536;
|
|
6455
6497
|
var MAX_NAMED_KEY_CODE_UNITS = 1048576;
|
|
@@ -6504,7 +6546,7 @@ function createLiveHostObject(definition, controller) {
|
|
|
6504
6546
|
for (const name of ["keys", "get", "set", "delete"]) {
|
|
6505
6547
|
const operation = data[name];
|
|
6506
6548
|
if (operation === void 0 && (name === "set" || name === "delete")) continue;
|
|
6507
|
-
if (typeof operation !== "function" ||
|
|
6549
|
+
if (typeof operation !== "function" || types4.isProxy(operation) || types4.isAsyncFunction(operation) || types4.isGeneratorFunction(operation))
|
|
6508
6550
|
throw new TypeError(`Named ${name} must be a synchronous non-generator function, not a proxy.`);
|
|
6509
6551
|
}
|
|
6510
6552
|
if (typeof data.maxKeys !== "number" || !Number.isInteger(data.maxKeys) || data.maxKeys < 1 || data.maxKeys > MAX_NAMED_KEYS)
|
|
@@ -6759,7 +6801,7 @@ function namedMutationKeys(state, key, create) {
|
|
|
6759
6801
|
function namedKeys(state) {
|
|
6760
6802
|
const named = state.named;
|
|
6761
6803
|
return state.controller.read(named.keys, (value) => {
|
|
6762
|
-
if (!Array.isArray(value) ||
|
|
6804
|
+
if (!Array.isArray(value) || types4.isProxy(value))
|
|
6763
6805
|
throw new TypeError("Named keys must be a dense own-data array of strings, not a proxy.");
|
|
6764
6806
|
const length = Object.getOwnPropertyDescriptor(value, "length").value;
|
|
6765
6807
|
if (length > named.maxKeys) throw new RangeError("Named keys exceed maxKeys.");
|
|
@@ -6912,7 +6954,7 @@ async function flushPromiseJobs() {
|
|
|
6912
6954
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
6913
6955
|
|
|
6914
6956
|
// packages/safe-js/src/snapshot/validation.ts
|
|
6915
|
-
import { types as
|
|
6957
|
+
import { types as types5 } from "node:util";
|
|
6916
6958
|
|
|
6917
6959
|
// packages/safe-js/src/interp/arguments.ts
|
|
6918
6960
|
var sandboxArgumentsBrand = /* @__PURE__ */ Symbol("SandboxArguments");
|
|
@@ -7017,6 +7059,7 @@ function walkGraphDepth(root, rootPath, assertDepth) {
|
|
|
7017
7059
|
}
|
|
7018
7060
|
}
|
|
7019
7061
|
function graphEntries(value) {
|
|
7062
|
+
if (isSandboxBox(value)) return boxedDataProperties(value).map(([key, descriptor]) => [`.${key}`, descriptor.value]);
|
|
7020
7063
|
if (isSandboxArguments(value)) {
|
|
7021
7064
|
return getSandboxArgumentEntries(value).map(([key, entry]) => [`.${key}`, entry]);
|
|
7022
7065
|
}
|
|
@@ -7046,7 +7089,10 @@ var guestClosures = /* @__PURE__ */ new WeakSet();
|
|
|
7046
7089
|
var functionProperties = /* @__PURE__ */ new WeakMap();
|
|
7047
7090
|
var prototypes = /* @__PURE__ */ new WeakMap();
|
|
7048
7091
|
var intrinsicPrototypes = /* @__PURE__ */ new WeakMap();
|
|
7092
|
+
var boxedPrototypes = /* @__PURE__ */ new WeakMap();
|
|
7093
|
+
var intrinsicPrototypeRoots = /* @__PURE__ */ new WeakMap();
|
|
7049
7094
|
var intrinsicConstructors = /* @__PURE__ */ new WeakMap();
|
|
7095
|
+
var initialBoxedMethods = /* @__PURE__ */ new WeakMap();
|
|
7050
7096
|
var descriptorObjects = /* @__PURE__ */ new WeakSet();
|
|
7051
7097
|
function registerGuestClosure(closure) {
|
|
7052
7098
|
guestClosures.add(closure);
|
|
@@ -7094,25 +7140,61 @@ function getGuestFunctionProperty(closure, key) {
|
|
|
7094
7140
|
function installObjectPrototype(budget, prototype, constructor) {
|
|
7095
7141
|
prototypes.set(prototype, null);
|
|
7096
7142
|
intrinsicPrototypes.set(budget, prototype);
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7143
|
+
registerIntrinsicPrototype(budget, prototype, constructor);
|
|
7144
|
+
}
|
|
7145
|
+
function installBoxedPrototype(budget, prototype, constructor) {
|
|
7146
|
+
let state = boxedPrototypes.get(budget);
|
|
7147
|
+
if (state === void 0) boxedPrototypes.set(budget, state = /* @__PURE__ */ new Map());
|
|
7148
|
+
state.set(typeof boxedValue(prototype), prototype);
|
|
7149
|
+
initialBoxedMethods.set(prototype, new Map(Object.entries(Object.getOwnPropertyDescriptors(prototype)).map(([key, descriptor]) => [key, descriptor.value])));
|
|
7150
|
+
registerIntrinsicPrototype(budget, prototype, constructor);
|
|
7151
|
+
}
|
|
7152
|
+
function getBoxedPrototype(value, budget) {
|
|
7153
|
+
return boxedPrototypes.get(budget)?.get(typeof value);
|
|
7154
|
+
}
|
|
7155
|
+
function isDefaultBoxedMethod(value, key, budget) {
|
|
7156
|
+
const prototype = getBoxedPrototype(value, budget);
|
|
7157
|
+
return prototype !== void 0 && initialBoxedMethods.get(prototype)?.has(key) === true && Object.getOwnPropertyDescriptor(prototype, key)?.value === initialBoxedMethods.get(prototype)?.get(key);
|
|
7158
|
+
}
|
|
7159
|
+
function isIntrinsicConstructor(value) {
|
|
7160
|
+
return intrinsicConstructors.has(value);
|
|
7161
|
+
}
|
|
7162
|
+
function registerIntrinsicPrototype(budget, prototype, constructor) {
|
|
7163
|
+
let roots = intrinsicPrototypeRoots.get(budget);
|
|
7164
|
+
if (roots === void 0) intrinsicPrototypeRoots.set(budget, roots = /* @__PURE__ */ new Set());
|
|
7165
|
+
roots.add(prototype);
|
|
7166
|
+
const records = [prototype, constructor].map((target) => ({
|
|
7167
|
+
target,
|
|
7168
|
+
value: isGuestClosure(target) ? materializeFunctionProperties(target) : target,
|
|
7169
|
+
prototype: getSandboxPrototype(target),
|
|
7170
|
+
explicit: hasExplicitSandboxPrototype(target)
|
|
7171
|
+
})).map((record2) => ({
|
|
7172
|
+
...record2,
|
|
7173
|
+
descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(record2.value)))
|
|
7100
7174
|
}));
|
|
7101
|
-
const unchanged = (before, after) => before !== void 0 && after !== void 0 && before.value
|
|
7102
|
-
intrinsicConstructors.set(constructor, () => records.every(({ value, descriptors }) => {
|
|
7175
|
+
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;
|
|
7176
|
+
intrinsicConstructors.set(constructor, () => records.every(({ target, value, descriptors, prototype: parent, explicit }) => {
|
|
7103
7177
|
const current = Object.getOwnPropertyDescriptors(value);
|
|
7104
|
-
return Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
|
|
7178
|
+
return getSandboxPrototype(target) === parent && hasExplicitSandboxPrototype(target) === explicit && Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
|
|
7105
7179
|
}));
|
|
7106
|
-
budget.setRetainedValues(prototype, () => records.flatMap(({
|
|
7180
|
+
budget.setRetainedValues(prototype, () => records.flatMap(({ target, value, descriptors, prototype: parent }) => [
|
|
7181
|
+
...getSandboxPrototype(target) === parent ? [] : [getSandboxPrototype(target)],
|
|
7182
|
+
...Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key, descriptor]) => unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value])
|
|
7183
|
+
]));
|
|
7107
7184
|
}
|
|
7108
7185
|
function releaseObjectPrototype(budget) {
|
|
7109
|
-
const prototype
|
|
7110
|
-
|
|
7186
|
+
for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
|
|
7187
|
+
intrinsicPrototypeRoots.delete(budget);
|
|
7188
|
+
boxedPrototypes.delete(budget);
|
|
7111
7189
|
intrinsicPrototypes.delete(budget);
|
|
7112
7190
|
}
|
|
7113
7191
|
function getSandboxPrototype(value, budget) {
|
|
7114
7192
|
if (prototypes.has(value)) return prototypes.get(value) ?? null;
|
|
7115
|
-
|
|
7193
|
+
if (budget !== void 0 && isSandboxBox(value)) {
|
|
7194
|
+
const prototype = getBoxedPrototype(boxedValue(value), budget);
|
|
7195
|
+
if (prototype !== void 0 && prototype !== value) return prototype;
|
|
7196
|
+
}
|
|
7197
|
+
return budget !== void 0 && !isSandboxClosure(value) && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
|
|
7116
7198
|
}
|
|
7117
7199
|
function hasExplicitSandboxPrototype(value) {
|
|
7118
7200
|
return prototypes.has(value);
|
|
@@ -7122,14 +7204,16 @@ function getSandboxDataProperty(value, key, budget) {
|
|
|
7122
7204
|
let depth = 0;
|
|
7123
7205
|
while (typeof current === "object" && current !== null) {
|
|
7124
7206
|
if (isGuestHostObject(current)) return getHostObjectMember(current, String(key));
|
|
7125
|
-
if (isGuestClosure(current))
|
|
7126
|
-
|
|
7207
|
+
if (isGuestClosure(current)) {
|
|
7208
|
+
const entry = getGuestFunctionProperty(current, String(key));
|
|
7209
|
+
if (entry !== void 0 || Object.hasOwn(current.properties ?? {}, String(key))) return entry;
|
|
7210
|
+
} else if (isSandboxClosure(current)) {
|
|
7127
7211
|
const properties = current.properties;
|
|
7128
7212
|
return properties !== void 0 && Object.hasOwn(properties, String(key)) ? properties[String(key)] : void 0;
|
|
7129
7213
|
}
|
|
7130
7214
|
if (isSandboxMap(current) || isSandboxSet(current) || isSandboxPromise(current) || isSandboxRegex(current) || isSandboxGenerator(current))
|
|
7131
7215
|
return void 0;
|
|
7132
|
-
if (Object.hasOwn(current, String(key))) return current[String(key)];
|
|
7216
|
+
if (!isSandboxClosure(current) && Object.hasOwn(current, String(key))) return current[String(key)];
|
|
7133
7217
|
current = getSandboxPrototype(current, budget);
|
|
7134
7218
|
if (current !== null) {
|
|
7135
7219
|
budget?.visitNode();
|
|
@@ -7144,7 +7228,7 @@ function setSandboxPrototype(value, prototype, budget) {
|
|
|
7144
7228
|
}
|
|
7145
7229
|
if (!isPrototypeRecord(value) || prototype !== null && !isPrototypeRecord(prototype)) {
|
|
7146
7230
|
throw new TypeError(
|
|
7147
|
-
"Prototype links require ordinary sandbox objects
|
|
7231
|
+
"Prototype links require ordinary sandbox objects or guest functions."
|
|
7148
7232
|
);
|
|
7149
7233
|
}
|
|
7150
7234
|
if (prototypes.has(value) && getSandboxPrototype(value, budget) === prototype) return;
|
|
@@ -7160,6 +7244,7 @@ function setSandboxPrototype(value, prototype, budget) {
|
|
|
7160
7244
|
prototypes.set(value, prototype);
|
|
7161
7245
|
}
|
|
7162
7246
|
function isPrototypeRecord(value) {
|
|
7247
|
+
if (isGuestClosure(value)) return true;
|
|
7163
7248
|
if (isGuestHostObject(value)) return false;
|
|
7164
7249
|
if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxSet(value))
|
|
7165
7250
|
return false;
|
|
@@ -7177,6 +7262,7 @@ function hasGuestObjectState(value) {
|
|
|
7177
7262
|
if (intrinsicUnchanged !== void 0) return !intrinsicUnchanged();
|
|
7178
7263
|
if (isLiveCapability(value)) return true;
|
|
7179
7264
|
if (functionProperties.has(value) || prototypes.has(value)) return true;
|
|
7265
|
+
if (isSandboxBox(value)) return false;
|
|
7180
7266
|
return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
|
|
7181
7267
|
(descriptor) => !descriptor.enumerable || !descriptor.configurable || !descriptor.writable
|
|
7182
7268
|
);
|
|
@@ -7280,6 +7366,34 @@ function decodeFloat32Storage(value, resolve) {
|
|
|
7280
7366
|
return new Float32Array(buffer, Number(value.byteOffset), Number(value.length));
|
|
7281
7367
|
}
|
|
7282
7368
|
|
|
7369
|
+
// packages/safe-js/src/snapshot/boxed.ts
|
|
7370
|
+
function encodeBoxedData(value, encode) {
|
|
7371
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
7372
|
+
for (const [key, descriptor] of boxedDataProperties(value)) {
|
|
7373
|
+
if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
|
|
7374
|
+
properties[key] = {
|
|
7375
|
+
value: encode(descriptor.value, key),
|
|
7376
|
+
configurable: descriptor.configurable === true,
|
|
7377
|
+
enumerable: descriptor.enumerable === true,
|
|
7378
|
+
writable: descriptor.writable === true
|
|
7379
|
+
};
|
|
7380
|
+
}
|
|
7381
|
+
return {
|
|
7382
|
+
kind: "boxed",
|
|
7383
|
+
value: encode(boxedValue(value), "<payload>"),
|
|
7384
|
+
properties,
|
|
7385
|
+
extensible: Object.isExtensible(value)
|
|
7386
|
+
};
|
|
7387
|
+
}
|
|
7388
|
+
function validateBoxedProperties(data) {
|
|
7389
|
+
if (!Object.hasOwn(data, "kind") || data.kind !== "boxed" || !Object.hasOwn(data, "value") || !Object.hasOwn(data, "extensible") || !Object.hasOwn(data, "properties") || Object.keys(data).length !== 4 || typeof data.extensible !== "boolean" || typeof data.properties !== "object" || data.properties === null || Array.isArray(data.properties))
|
|
7390
|
+
throw new TypeError("Invalid boxed primitive properties.");
|
|
7391
|
+
for (const descriptor of Object.values(data.properties)) {
|
|
7392
|
+
if (typeof descriptor !== "object" || descriptor === null || !Object.hasOwn(descriptor, "value") || !Object.hasOwn(descriptor, "writable") || !Object.hasOwn(descriptor, "enumerable") || !Object.hasOwn(descriptor, "configurable") || typeof descriptor.writable !== "boolean" || typeof descriptor.enumerable !== "boolean" || typeof descriptor.configurable !== "boolean" || Object.keys(descriptor).length !== 4)
|
|
7393
|
+
throw new TypeError("Invalid boxed primitive descriptor.");
|
|
7394
|
+
}
|
|
7395
|
+
}
|
|
7396
|
+
|
|
7283
7397
|
// packages/safe-js/src/snapshot/dump-format.ts
|
|
7284
7398
|
var DUMP_FORMAT_VERSION = 1;
|
|
7285
7399
|
var EXECUTION_SEMANTICS = "jobs-v8";
|
|
@@ -7341,7 +7455,7 @@ function serializeDumpValue(value, path, state) {
|
|
|
7341
7455
|
if (hasGuestObjectState(value)) {
|
|
7342
7456
|
throw new TypeError("Guest function properties and prototype links cannot be serialized.");
|
|
7343
7457
|
}
|
|
7344
|
-
if (isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path, state);
|
|
7458
|
+
if (isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path, state);
|
|
7345
7459
|
if (Array.isArray(value)) {
|
|
7346
7460
|
const reference2 = serializeHeapReference(value, path, state);
|
|
7347
7461
|
if (reference2 !== void 0) {
|
|
@@ -7365,7 +7479,13 @@ function serializeHeapReference(value, path, state) {
|
|
|
7365
7479
|
}
|
|
7366
7480
|
if (!state.serializedHeapIds.has(id)) {
|
|
7367
7481
|
state.serializedHeapIds.add(id);
|
|
7368
|
-
if (
|
|
7482
|
+
if (isSandboxBox(value)) {
|
|
7483
|
+
state.heap[String(id)] = encodeBoxedData(value, (entry, key) => {
|
|
7484
|
+
if (Object.is(entry, -0)) return { kind: "number", value: "-0" };
|
|
7485
|
+
const serialized = serializeDumpValue(entry, `${path}.${key}`, state);
|
|
7486
|
+
return serialized === SKIP_VALUE ? { kind: "undefined" } : serialized;
|
|
7487
|
+
});
|
|
7488
|
+
} else if (isSandboxDate(value)) {
|
|
7369
7489
|
state.heap[String(id)] = { kind: "date", time: serializedDateTime(value) };
|
|
7370
7490
|
} else if (isFloat32Array(value)) {
|
|
7371
7491
|
const storage = encodeFloat32Storage(value, id, state.float32Buffers, (id2) => ({
|
|
@@ -7424,7 +7544,7 @@ function indexHeapContainers(snapshot) {
|
|
|
7424
7544
|
const heapIds = /* @__PURE__ */ new WeakMap();
|
|
7425
7545
|
let nextId = 1;
|
|
7426
7546
|
for (const [value, stat2] of stats.entries()) {
|
|
7427
|
-
if (stat2.count > 1 || stat2.cyclic || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
|
|
7547
|
+
if (stat2.count > 1 || stat2.cyclic || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
|
|
7428
7548
|
heapIds.set(value, nextId);
|
|
7429
7549
|
nextId += 1;
|
|
7430
7550
|
}
|
|
@@ -7457,7 +7577,7 @@ function collectContainerStats(value, stats, ancestors) {
|
|
|
7457
7577
|
}
|
|
7458
7578
|
stat2.expanded = true;
|
|
7459
7579
|
ancestors.add(value);
|
|
7460
|
-
const entries = isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
|
|
7580
|
+
const entries = isSandboxBox(value) ? boxedDataProperties(value).map(([, descriptor]) => descriptor.value) : isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
|
|
7461
7581
|
for (const entry of entries) {
|
|
7462
7582
|
collectContainerStats(entry, stats, ancestors);
|
|
7463
7583
|
}
|
|
@@ -7571,6 +7691,10 @@ function validateDumpHeap(root, state) {
|
|
|
7571
7691
|
addUnique(heapIds, id, path);
|
|
7572
7692
|
const entry = requireRecord(value, path);
|
|
7573
7693
|
validateErrorType(entry, path);
|
|
7694
|
+
if (entry.kind === "boxed") {
|
|
7695
|
+
validateBoxedRecord(entry, path);
|
|
7696
|
+
continue;
|
|
7697
|
+
}
|
|
7574
7698
|
if (entry.kind === "date") {
|
|
7575
7699
|
validateDateRecord(entry, path);
|
|
7576
7700
|
continue;
|
|
@@ -7738,6 +7862,18 @@ function validateGeneratorShape(record2, path, state) {
|
|
|
7738
7862
|
}
|
|
7739
7863
|
});
|
|
7740
7864
|
}
|
|
7865
|
+
function validateBoxedRecord(record2, path) {
|
|
7866
|
+
try {
|
|
7867
|
+
validateBoxedProperties(record2);
|
|
7868
|
+
} catch {
|
|
7869
|
+
fail("invalidValue", path, "invalid boxed primitive properties");
|
|
7870
|
+
}
|
|
7871
|
+
const value = record2.value;
|
|
7872
|
+
if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") return;
|
|
7873
|
+
const number = requireRecord(value, `${path}.value`);
|
|
7874
|
+
if (number.kind !== "number" || !["NaN", "Infinity", "-Infinity", "-0"].includes(String(number.value)))
|
|
7875
|
+
fail("invalidValue", `${path}.value`, "invalid boxed primitive payload");
|
|
7876
|
+
}
|
|
7741
7877
|
function validateDateRecord(record2, path) {
|
|
7742
7878
|
if (Object.keys(record2).length !== 2) fail("invalidValue", path, "invalid Date fields");
|
|
7743
7879
|
try {
|
|
@@ -7829,7 +7965,7 @@ function validateGenericValue(value, path, depth, state) {
|
|
|
7829
7965
|
if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
|
|
7830
7966
|
fail("invalidState", path, "guest function properties, prototype links and custom descriptors cannot be restored");
|
|
7831
7967
|
}
|
|
7832
|
-
if (state.dataPropertiesOnly &&
|
|
7968
|
+
if (state.dataPropertiesOnly && types5.isProxy(value)) {
|
|
7833
7969
|
fail("invalidType", path, "proxy objects are not snapshot data");
|
|
7834
7970
|
}
|
|
7835
7971
|
if (depth > state.limits.maxDepth)
|
|
@@ -8754,7 +8890,7 @@ async function objectToPrimitive(value, budget, context, joining, hint) {
|
|
|
8754
8890
|
if (hook === defaultStringHook) {
|
|
8755
8891
|
result = await defaultToString(value, budget, context, joining);
|
|
8756
8892
|
} else if (hook === defaultValueHook) {
|
|
8757
|
-
result = isSandboxDate(value) ? dateTime(value) : value;
|
|
8893
|
+
result = isSandboxDate(value) ? dateTime(value) : isSandboxBox(value) ? boxedValue(value) : value;
|
|
8758
8894
|
} else {
|
|
8759
8895
|
if (!isSandboxClosure(hook)) continue;
|
|
8760
8896
|
result = await invokeBuiltinClosure(hook, [], budget, context, value);
|
|
@@ -8794,6 +8930,7 @@ function conversionHook(value, name, budget) {
|
|
|
8794
8930
|
return void 0;
|
|
8795
8931
|
}
|
|
8796
8932
|
async function defaultToString(value, budget, context, joining) {
|
|
8933
|
+
if (isSandboxBox(value)) return budget.allocateString(String(boxedValue(value)));
|
|
8797
8934
|
if (isSandboxClosure(value)) return budget.allocateString(functionString(value));
|
|
8798
8935
|
if (isSandboxMap(value)) return "[object Map]";
|
|
8799
8936
|
if (isSandboxSet(value)) return "[object Set]";
|
|
@@ -9350,7 +9487,27 @@ function assertSnapshotInactive(snapshot) {
|
|
|
9350
9487
|
}
|
|
9351
9488
|
|
|
9352
9489
|
// packages/safe-js/src/interp/iteration.ts
|
|
9353
|
-
function getSandboxIterator(value, budget) {
|
|
9490
|
+
function getSandboxIterator(value, budget, context) {
|
|
9491
|
+
if (isSandboxBox(value) && typeof boxedValue(value) === "string") {
|
|
9492
|
+
const primitive = boxedValue(value);
|
|
9493
|
+
let text;
|
|
9494
|
+
let iterator;
|
|
9495
|
+
let initialized;
|
|
9496
|
+
return {
|
|
9497
|
+
asynchronous: true,
|
|
9498
|
+
get retainedValue() {
|
|
9499
|
+
return text === primitive ? void 0 : text;
|
|
9500
|
+
},
|
|
9501
|
+
next: async () => {
|
|
9502
|
+
initialized ??= Promise.resolve(sandboxString(value, budget ?? new Budget(), context)).then((converted) => {
|
|
9503
|
+
text = converted;
|
|
9504
|
+
iterator = syncIterator(converted[Symbol.iterator]());
|
|
9505
|
+
});
|
|
9506
|
+
await initialized;
|
|
9507
|
+
return iterator.next();
|
|
9508
|
+
}
|
|
9509
|
+
};
|
|
9510
|
+
}
|
|
9354
9511
|
if (isSandboxCollectionIterator(value)) return { next: () => nextCollectionIterator(value, budget), snapshotIndex: () => 0 };
|
|
9355
9512
|
if (isGuestHostObject(value)) return getHostObjectIterator(value);
|
|
9356
9513
|
if (isFloat32Array(value)) {
|
|
@@ -9917,67 +10074,72 @@ async function settleIterable(iterable, method, budget, constructor, context) {
|
|
|
9917
10074
|
const promiseResolve = readPromiseReceiverProperty(constructor, "resolve", prototype);
|
|
9918
10075
|
if (!isSandboxClosure(promiseResolve))
|
|
9919
10076
|
throw new TypeError("Promise constructor requires a callable resolve.");
|
|
9920
|
-
const iterator = getSandboxIterator(iterable, budget);
|
|
10077
|
+
const iterator = getSandboxIterator(iterable, budget, context);
|
|
9921
10078
|
if (iterator === void 0) throw new TypeError("Promise helpers require an iterable.");
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
const entryIndex = index++;
|
|
9933
|
-
if (method !== "race") values.push(void 0);
|
|
9934
|
-
const entry = await callPromiseClosure(
|
|
9935
|
-
promiseResolve,
|
|
9936
|
-
[value],
|
|
9937
|
-
constructor,
|
|
9938
|
-
budget,
|
|
9939
|
-
context
|
|
9940
|
-
);
|
|
9941
|
-
let called = false;
|
|
9942
|
-
const handlers = ["fulfilled", "rejected"].map((state) => {
|
|
9943
|
-
if (method === "race" || method === "any" && state === "fulfilled")
|
|
9944
|
-
return state === "fulfilled" ? capability.resolve : capability.reject;
|
|
9945
|
-
if (method === "all" && state === "rejected") return capability.reject;
|
|
9946
|
-
return createSandboxClosure({
|
|
9947
|
-
sandbox: true,
|
|
9948
|
-
retainedValues: () => [
|
|
9949
|
-
capability.promise,
|
|
9950
|
-
capability.resolve,
|
|
9951
|
-
capability.reject,
|
|
9952
|
-
values
|
|
9953
|
-
],
|
|
9954
|
-
call: async ([settlement]) => {
|
|
9955
|
-
if (called) return void 0;
|
|
9956
|
-
called = true;
|
|
9957
|
-
values[entryIndex] = method === "allSettled" ? state === "fulfilled" ? { status: state, value: settlement } : { status: state, reason: settlement } : settlement;
|
|
9958
|
-
remaining--;
|
|
9959
|
-
await complete();
|
|
9960
|
-
return void 0;
|
|
9961
|
-
}
|
|
9962
|
-
});
|
|
9963
|
-
});
|
|
9964
|
-
remaining++;
|
|
9965
|
-
const then = readPromiseReceiverProperty(entry, "then", prototype);
|
|
9966
|
-
if (!isSandboxClosure(then))
|
|
9967
|
-
throw new TypeError("Promise resolver result requires a callable then.");
|
|
9968
|
-
await callPromiseClosure(then, handlers, entry, budget, context);
|
|
9969
|
-
} catch (error) {
|
|
10079
|
+
const releaseIterator = retainValues(budget, () => [iterator.retainedValue]);
|
|
10080
|
+
try {
|
|
10081
|
+
let index = 0;
|
|
10082
|
+
while (true) {
|
|
10083
|
+
budget.visitNode();
|
|
10084
|
+
const next = iterator.generator || iterator.asynchronous ? await iterator.next() : iterator.next();
|
|
10085
|
+
if (typeof next !== "object" || next === null)
|
|
10086
|
+
throw new TypeError("Iterator result must be an object.");
|
|
10087
|
+
if (next.done) break;
|
|
10088
|
+
const value = next.value;
|
|
9970
10089
|
try {
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
10090
|
+
budget.allocateArrayLength(index + 1);
|
|
10091
|
+
const entryIndex = index++;
|
|
10092
|
+
if (method !== "race") values.push(void 0);
|
|
10093
|
+
const entry = await callPromiseClosure(
|
|
10094
|
+
promiseResolve,
|
|
10095
|
+
[value],
|
|
10096
|
+
constructor,
|
|
10097
|
+
budget,
|
|
10098
|
+
context
|
|
10099
|
+
);
|
|
10100
|
+
let called = false;
|
|
10101
|
+
const handlers = ["fulfilled", "rejected"].map((state) => {
|
|
10102
|
+
if (method === "race" || method === "any" && state === "fulfilled")
|
|
10103
|
+
return state === "fulfilled" ? capability.resolve : capability.reject;
|
|
10104
|
+
if (method === "all" && state === "rejected") return capability.reject;
|
|
10105
|
+
return createSandboxClosure({
|
|
10106
|
+
sandbox: true,
|
|
10107
|
+
retainedValues: () => [
|
|
10108
|
+
capability.promise,
|
|
10109
|
+
capability.resolve,
|
|
10110
|
+
capability.reject,
|
|
10111
|
+
values
|
|
10112
|
+
],
|
|
10113
|
+
call: async ([settlement]) => {
|
|
10114
|
+
if (called) return void 0;
|
|
10115
|
+
called = true;
|
|
10116
|
+
values[entryIndex] = method === "allSettled" ? state === "fulfilled" ? { status: state, value: settlement } : { status: state, reason: settlement } : settlement;
|
|
10117
|
+
remaining--;
|
|
10118
|
+
await complete();
|
|
10119
|
+
return void 0;
|
|
10120
|
+
}
|
|
10121
|
+
});
|
|
10122
|
+
});
|
|
10123
|
+
remaining++;
|
|
10124
|
+
const then = readPromiseReceiverProperty(entry, "then", prototype);
|
|
10125
|
+
if (!isSandboxClosure(then))
|
|
10126
|
+
throw new TypeError("Promise resolver result requires a callable then.");
|
|
10127
|
+
await callPromiseClosure(then, handlers, entry, budget, context);
|
|
10128
|
+
} catch (error) {
|
|
10129
|
+
try {
|
|
10130
|
+
const closed = iterator.return?.();
|
|
10131
|
+
if (iterator.generator || iterator.asynchronous) await closed;
|
|
10132
|
+
} catch {
|
|
10133
|
+
throw error;
|
|
10134
|
+
}
|
|
9974
10135
|
throw error;
|
|
9975
10136
|
}
|
|
9976
|
-
throw error;
|
|
9977
10137
|
}
|
|
10138
|
+
remaining--;
|
|
10139
|
+
await complete();
|
|
10140
|
+
} finally {
|
|
10141
|
+
releaseIterator();
|
|
9978
10142
|
}
|
|
9979
|
-
remaining--;
|
|
9980
|
-
await complete();
|
|
9981
10143
|
} catch (error) {
|
|
9982
10144
|
if (error instanceof SandboxError && (error.code === "budgetExceeded" || error.code === "reentry")) {
|
|
9983
10145
|
if (isSandboxPromise(capability.promise)) observeSandboxPromise(capability.promise);
|
|
@@ -10679,6 +10841,17 @@ function measureSandboxData(values, options = {}) {
|
|
|
10679
10841
|
assertSandboxDataDepth(depth);
|
|
10680
10842
|
seen.add(value);
|
|
10681
10843
|
usage += 1;
|
|
10844
|
+
if (isSandboxBox(value)) {
|
|
10845
|
+
const primitive = boxedValue(value);
|
|
10846
|
+
usage += typeof primitive === "string" ? primitive.length : 8;
|
|
10847
|
+
const prototype2 = getSandboxPrototype(value);
|
|
10848
|
+
if (prototype2 !== null) visit(prototype2, depth + 1);
|
|
10849
|
+
for (const [key, descriptor] of boxedDataProperties(value)) {
|
|
10850
|
+
usage += key.length + 1;
|
|
10851
|
+
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
10852
|
+
}
|
|
10853
|
+
return;
|
|
10854
|
+
}
|
|
10682
10855
|
if (isSandboxDate(value)) {
|
|
10683
10856
|
usage += 8;
|
|
10684
10857
|
return;
|
|
@@ -10740,7 +10913,15 @@ function measureSandboxData(values, options = {}) {
|
|
|
10740
10913
|
}
|
|
10741
10914
|
if (isSandboxClosure(value)) {
|
|
10742
10915
|
if (options.ignoreClosures) return;
|
|
10743
|
-
if (value.properties !== void 0)
|
|
10916
|
+
if (value.properties !== void 0) {
|
|
10917
|
+
if (isIntrinsicConstructor(value)) {
|
|
10918
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value.properties))) {
|
|
10919
|
+
if (key === "prototype" || key === "name" || key === "length") continue;
|
|
10920
|
+
usage += key.length + 1;
|
|
10921
|
+
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
10922
|
+
}
|
|
10923
|
+
} else visit(value.properties, depth + 1);
|
|
10924
|
+
}
|
|
10744
10925
|
if (!options.ignoreClosureCaptures)
|
|
10745
10926
|
for (const retained of value[sandboxRetainedValues]?.() ?? []) visit(retained, depth + 1);
|
|
10746
10927
|
return;
|
|
@@ -10872,6 +11053,24 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
10872
11053
|
if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
|
|
10873
11054
|
throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
|
|
10874
11055
|
}
|
|
11056
|
+
const primitive = nativeBoxedValue(value);
|
|
11057
|
+
if (primitive !== void 0) {
|
|
11058
|
+
const original = value;
|
|
11059
|
+
const existing = state.seen.get(original);
|
|
11060
|
+
if (existing !== void 0) return existing;
|
|
11061
|
+
const copy = createSandboxBox(primitive);
|
|
11062
|
+
state.seen.set(original, copy);
|
|
11063
|
+
if (!state.structuredClone) {
|
|
11064
|
+
for (const [key, descriptor] of boxedDataProperties(original)) {
|
|
11065
|
+
if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
|
|
11066
|
+
Object.defineProperty(copy, key, {
|
|
11067
|
+
...descriptor,
|
|
11068
|
+
value: copyToSandbox(descriptor.value, state, joinPath(path, key), cloneSandboxCollections, depth + 1)
|
|
11069
|
+
});
|
|
11070
|
+
}
|
|
11071
|
+
}
|
|
11072
|
+
return copy;
|
|
11073
|
+
}
|
|
10875
11074
|
if (isSandboxMap(value)) {
|
|
10876
11075
|
if (!cloneSandboxCollections) return value;
|
|
10877
11076
|
const existing = state.seen.get(value);
|
|
@@ -11044,6 +11243,20 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
11044
11243
|
if (!isSandboxClosure(value) && hasGuestObjectState(value)) {
|
|
11045
11244
|
throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
|
|
11046
11245
|
}
|
|
11246
|
+
if (isSandboxBox(value)) {
|
|
11247
|
+
const existing = state.seen.get(value);
|
|
11248
|
+
if (existing !== void 0) return existing;
|
|
11249
|
+
const copy = Object(boxedValue(value));
|
|
11250
|
+
state.seen.set(value, copy);
|
|
11251
|
+
for (const [key, descriptor] of boxedDataProperties(value)) {
|
|
11252
|
+
if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
|
|
11253
|
+
Object.defineProperty(copy, key, {
|
|
11254
|
+
...descriptor,
|
|
11255
|
+
value: copyFromSandbox(descriptor.value, state, joinPath(path, key), options, depth + 1)
|
|
11256
|
+
});
|
|
11257
|
+
}
|
|
11258
|
+
return copy;
|
|
11259
|
+
}
|
|
11047
11260
|
const regexBrand = Object.getOwnPropertyDescriptor(value, sandboxRegexBrand);
|
|
11048
11261
|
if (regexBrand !== void 0) {
|
|
11049
11262
|
if (!("value" in regexBrand) || regexBrand.value !== true) {
|
|
@@ -11214,6 +11427,17 @@ function allocateSandboxValue2(value, budget, seen) {
|
|
|
11214
11427
|
budget.allocateString(value);
|
|
11215
11428
|
return;
|
|
11216
11429
|
}
|
|
11430
|
+
if (isSandboxBox(value)) {
|
|
11431
|
+
if (seen.has(value)) return;
|
|
11432
|
+
seen.add(value);
|
|
11433
|
+
const primitive = boxedValue(value);
|
|
11434
|
+
if (typeof primitive === "string") budget.allocateString(primitive);
|
|
11435
|
+
for (const [key, descriptor] of boxedDataProperties(value)) {
|
|
11436
|
+
budget.allocateString(key);
|
|
11437
|
+
if ("value" in descriptor) allocateSandboxValue2(descriptor.value, budget, seen);
|
|
11438
|
+
}
|
|
11439
|
+
return;
|
|
11440
|
+
}
|
|
11217
11441
|
if (isFloat32Array(value)) {
|
|
11218
11442
|
if (seen.has(value)) return;
|
|
11219
11443
|
seen.add(value);
|
|
@@ -11403,6 +11627,13 @@ function encodeReplayData(value, options = {}) {
|
|
|
11403
11627
|
id: capabilityId,
|
|
11404
11628
|
properties: child(entry.properties, "properties")
|
|
11405
11629
|
};
|
|
11630
|
+
} else if (nativeBoxedValue(entry) !== void 0) {
|
|
11631
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
11632
|
+
nodes[id] = { kind: "boxed", value: child(nativeBoxedValue(entry), "<payload>"), properties, extensible: Object.isExtensible(entry) };
|
|
11633
|
+
for (const [key, descriptor] of boxedDataProperties(entry)) {
|
|
11634
|
+
if (!("value" in descriptor)) throw new TypeError(`Cannot record replay data accessor '${key}'.`);
|
|
11635
|
+
properties[key] = { value: child(descriptor.value, JSON.stringify(["property", key])), configurable: descriptor.configurable === true, enumerable: descriptor.enumerable === true, writable: descriptor.writable === true };
|
|
11636
|
+
}
|
|
11406
11637
|
} else if (isSandboxDate(entry)) {
|
|
11407
11638
|
nodes[id] = { kind: "date", time: serializedDateTime(entry) };
|
|
11408
11639
|
} else if (isFloat32Array(entry)) {
|
|
@@ -11564,6 +11795,17 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
11564
11795
|
options.onCapabilityRestored?.(capability, copy);
|
|
11565
11796
|
return copy;
|
|
11566
11797
|
}
|
|
11798
|
+
if (kind === "boxed") {
|
|
11799
|
+
validateBoxedProperties(node);
|
|
11800
|
+
const payload = own(node, "value");
|
|
11801
|
+
if (typeof payload !== "number" && typeof payload !== "string" && typeof payload !== "boolean" && (payload === null || typeof payload !== "object" || own(record(payload), "tag") !== "number"))
|
|
11802
|
+
throw new TypeError("Invalid boxed primitive payload.");
|
|
11803
|
+
const result3 = createSandboxBox(child(payload));
|
|
11804
|
+
restored.set(id, result3);
|
|
11805
|
+
defineProperties(result3, record(own(node, "properties")), child);
|
|
11806
|
+
if (!node.extensible) Object.preventExtensions(result3);
|
|
11807
|
+
return result3;
|
|
11808
|
+
}
|
|
11567
11809
|
if (kind === "date") {
|
|
11568
11810
|
if (Object.keys(node).length !== 2) throw new TypeError("Invalid serialized Date fields.");
|
|
11569
11811
|
const result3 = restoreDateTime(own(node, "time"));
|
|
@@ -24086,7 +24328,10 @@ function isArrayMethodName(property) {
|
|
|
24086
24328
|
}
|
|
24087
24329
|
async function callArrayMethod(receiver, methodName, args, options, stack = []) {
|
|
24088
24330
|
if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
|
|
24089
|
-
if (typeof receiver !== "object")
|
|
24331
|
+
if (typeof receiver !== "object") {
|
|
24332
|
+
receiver = createSandboxBox(receiver);
|
|
24333
|
+
options.budget.chargeDataUsage(measureSandboxData([receiver]));
|
|
24334
|
+
}
|
|
24090
24335
|
const retainedReceiver = {};
|
|
24091
24336
|
options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
|
|
24092
24337
|
try {
|
|
@@ -24796,18 +25041,27 @@ function toIntegerOrInfinity(value) {
|
|
|
24796
25041
|
// packages/safe-js/src/interp/methods/function.ts
|
|
24797
25042
|
var functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call", "toString"]);
|
|
24798
25043
|
function getFunctionMember(target, property, options) {
|
|
24799
|
-
|
|
24800
|
-
|
|
24801
|
-
|
|
24802
|
-
if (
|
|
24803
|
-
|
|
24804
|
-
|
|
24805
|
-
|
|
24806
|
-
|
|
24807
|
-
|
|
24808
|
-
|
|
24809
|
-
|
|
25044
|
+
let current = target;
|
|
25045
|
+
let depth = 0;
|
|
25046
|
+
while (current !== null) {
|
|
25047
|
+
if (isGuestClosure(current)) {
|
|
25048
|
+
const value = getGuestFunctionProperty(current, String(property));
|
|
25049
|
+
if (value !== void 0 || Object.hasOwn(current.properties ?? {}, String(property))) return value;
|
|
25050
|
+
} else if (isSandboxClosure(current)) {
|
|
25051
|
+
if (current.properties !== void 0 && Object.hasOwn(current.properties, String(property)))
|
|
25052
|
+
return current.properties[String(property)];
|
|
25053
|
+
if (property === "length") return current.length;
|
|
25054
|
+
} else if (Object.hasOwn(current, String(property))) {
|
|
25055
|
+
return current[String(property)];
|
|
25056
|
+
}
|
|
25057
|
+
if (isSandboxClosure(current) && !hasExplicitSandboxPrototype(current)) break;
|
|
25058
|
+
current = getSandboxPrototype(current, options.budget);
|
|
25059
|
+
if (current !== null) {
|
|
25060
|
+
options.budget?.visitNode();
|
|
25061
|
+
assertSandboxDataDepth(++depth);
|
|
25062
|
+
}
|
|
24810
25063
|
}
|
|
25064
|
+
if (current === null) return void 0;
|
|
24811
25065
|
if (property === "toString" && runResources.getStore()?.functionSourceText === false) return void 0;
|
|
24812
25066
|
if (!isFunctionMethodName(property)) {
|
|
24813
25067
|
return void 0;
|
|
@@ -24833,7 +25087,7 @@ function callFunctionMethod(target, methodName, args, options, stack) {
|
|
|
24833
25087
|
const thisValue = args[0];
|
|
24834
25088
|
if (methodName === "bind") {
|
|
24835
25089
|
const boundArgs = args.slice(1);
|
|
24836
|
-
|
|
25090
|
+
const bound = createSandboxClosure({
|
|
24837
25091
|
guest: true,
|
|
24838
25092
|
sandbox: true,
|
|
24839
25093
|
name: `bound ${target.name ?? ""}`,
|
|
@@ -24851,6 +25105,9 @@ function callFunctionMethod(target, methodName, args, options, stack) {
|
|
|
24851
25105
|
)
|
|
24852
25106
|
}
|
|
24853
25107
|
});
|
|
25108
|
+
if (hasExplicitSandboxPrototype(target))
|
|
25109
|
+
setSandboxPrototype(bound, getSandboxPrototype(target, options.budget), options.budget);
|
|
25110
|
+
return bound;
|
|
24854
25111
|
}
|
|
24855
25112
|
if (methodName === "call") {
|
|
24856
25113
|
return options.callClosure(target, args.slice(1), stack, thisValue);
|
|
@@ -24865,273 +25122,58 @@ function callFunctionMethod(target, methodName, args, options, stack) {
|
|
|
24865
25122
|
return options.callClosure(target, applyArgs, stack, thisValue);
|
|
24866
25123
|
}
|
|
24867
25124
|
|
|
24868
|
-
// packages/safe-js/src/interp/methods/
|
|
24869
|
-
var
|
|
24870
|
-
|
|
24871
|
-
|
|
24872
|
-
|
|
24873
|
-
|
|
24874
|
-
|
|
24875
|
-
|
|
24876
|
-
|
|
24877
|
-
|
|
24878
|
-
|
|
24879
|
-
|
|
24880
|
-
|
|
24881
|
-
|
|
24882
|
-
|
|
24883
|
-
|
|
24884
|
-
|
|
24885
|
-
|
|
24886
|
-
|
|
24887
|
-
|
|
24888
|
-
|
|
24889
|
-
|
|
24890
|
-
|
|
24891
|
-
|
|
24892
|
-
|
|
24893
|
-
|
|
24894
|
-
|
|
24895
|
-
|
|
24896
|
-
|
|
24897
|
-
|
|
24898
|
-
|
|
24899
|
-
|
|
24900
|
-
|
|
24901
|
-
|
|
24902
|
-
return { done: false, value: key };
|
|
24903
|
-
}
|
|
24904
|
-
return { done: true, value: void 0 };
|
|
24905
|
-
},
|
|
24906
|
-
leave
|
|
24907
|
-
};
|
|
24908
|
-
}
|
|
24909
|
-
function updateKeyedCollectionCallbacks(target, mutation, key) {
|
|
24910
|
-
const state = activeCallbacks.get(target);
|
|
24911
|
-
if (state === void 0) return;
|
|
24912
|
-
for (const cursor of state.cursors) updatePendingKeys(cursor, mutation, key);
|
|
24913
|
-
}
|
|
24914
|
-
function updatePendingKeys(cursor, mutation, key) {
|
|
24915
|
-
const { budget, pending } = cursor;
|
|
24916
|
-
budget.visitNode();
|
|
24917
|
-
if (mutation === "add") {
|
|
24918
|
-
const nextSize = pending.has(key) ? pending.size : pending.size + 1;
|
|
24919
|
-
budget.allocateCollectionEntries(nextSize);
|
|
24920
|
-
budget.setRetainedDataUsage(cursor, 1 + nextSize);
|
|
24921
|
-
pending.add(key);
|
|
24922
|
-
} else {
|
|
24923
|
-
if (mutation === "delete") pending.delete(key);
|
|
24924
|
-
else pending.clear();
|
|
24925
|
-
budget.setRetainedDataUsage(cursor, 1 + pending.size);
|
|
24926
|
-
}
|
|
24927
|
-
}
|
|
24928
|
-
|
|
24929
|
-
// packages/safe-js/src/interp/methods/map.ts
|
|
24930
|
-
var mapMethodNames = /* @__PURE__ */ new Set([
|
|
24931
|
-
"get",
|
|
24932
|
-
"set",
|
|
24933
|
-
"has",
|
|
24934
|
-
"delete",
|
|
24935
|
-
"clear",
|
|
24936
|
-
"forEach",
|
|
24937
|
-
"keys",
|
|
24938
|
-
"values",
|
|
24939
|
-
"entries"
|
|
25125
|
+
// packages/safe-js/src/interp/methods/string.ts
|
|
25126
|
+
var SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
|
|
25127
|
+
var stringMethodNames = /* @__PURE__ */ new Set([
|
|
25128
|
+
"at",
|
|
25129
|
+
"charAt",
|
|
25130
|
+
"charCodeAt",
|
|
25131
|
+
"codePointAt",
|
|
25132
|
+
"concat",
|
|
25133
|
+
"endsWith",
|
|
25134
|
+
"includes",
|
|
25135
|
+
"indexOf",
|
|
25136
|
+
"isWellFormed",
|
|
25137
|
+
"lastIndexOf",
|
|
25138
|
+
"localeCompare",
|
|
25139
|
+
"match",
|
|
25140
|
+
"matchAll",
|
|
25141
|
+
"normalize",
|
|
25142
|
+
"padEnd",
|
|
25143
|
+
"padStart",
|
|
25144
|
+
"repeat",
|
|
25145
|
+
"replace",
|
|
25146
|
+
"replaceAll",
|
|
25147
|
+
"slice",
|
|
25148
|
+
"search",
|
|
25149
|
+
"split",
|
|
25150
|
+
"startsWith",
|
|
25151
|
+
"substr",
|
|
25152
|
+
"substring",
|
|
25153
|
+
"toLowerCase",
|
|
25154
|
+
"toUpperCase",
|
|
25155
|
+
"toWellFormed",
|
|
25156
|
+
"trim",
|
|
25157
|
+
"trimEnd",
|
|
25158
|
+
"trimStart"
|
|
24940
25159
|
]);
|
|
24941
|
-
function
|
|
24942
|
-
|
|
24943
|
-
|
|
24944
|
-
|
|
24945
|
-
if (property === "size") {
|
|
24946
|
-
return target.entries.size;
|
|
25160
|
+
function getStringMember(value, property, budget) {
|
|
25161
|
+
const index = getStringIndex(property);
|
|
25162
|
+
if (index !== void 0) {
|
|
25163
|
+
return value[index];
|
|
24947
25164
|
}
|
|
24948
|
-
if (
|
|
25165
|
+
if (property === "length") {
|
|
25166
|
+
return value.length;
|
|
25167
|
+
}
|
|
25168
|
+
if (!isStringMethodName(property)) {
|
|
24949
25169
|
return void 0;
|
|
24950
25170
|
}
|
|
24951
25171
|
return createSandboxClosure({
|
|
24952
25172
|
sandbox: true,
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
|
|
24956
|
-
|
|
24957
|
-
},
|
|
24958
|
-
name: property
|
|
24959
|
-
});
|
|
24960
|
-
}
|
|
24961
|
-
async function callMapMethod(target, methodName, args, options, stack = []) {
|
|
24962
|
-
switch (methodName) {
|
|
24963
|
-
case "get":
|
|
24964
|
-
return target.entries.get(args[0]);
|
|
24965
|
-
case "set": {
|
|
24966
|
-
assertCollectionMutable(target);
|
|
24967
|
-
const exists = target.entries.has(args[0]);
|
|
24968
|
-
const nextSize = exists ? target.entries.size : target.entries.size + 1;
|
|
24969
|
-
options.budget.allocateCollectionEntries(nextSize);
|
|
24970
|
-
if (!exists) updateKeyedCollectionCallbacks(target, "add", args[0]);
|
|
24971
|
-
target.entries.set(args[0], args[1]);
|
|
24972
|
-
return target;
|
|
24973
|
-
}
|
|
24974
|
-
case "has":
|
|
24975
|
-
return target.entries.has(args[0]);
|
|
24976
|
-
case "delete": {
|
|
24977
|
-
assertCollectionMutable(target);
|
|
24978
|
-
const deleted = target.entries.delete(args[0]);
|
|
24979
|
-
if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
|
|
24980
|
-
return deleted;
|
|
24981
|
-
}
|
|
24982
|
-
case "clear":
|
|
24983
|
-
assertCollectionMutable(target);
|
|
24984
|
-
target.entries.clear();
|
|
24985
|
-
updateKeyedCollectionCallbacks(target, "clear");
|
|
24986
|
-
return void 0;
|
|
24987
|
-
case "forEach": {
|
|
24988
|
-
const callback = args[0];
|
|
24989
|
-
if (!isSandboxClosure(callback)) {
|
|
24990
|
-
throw new TypeError("Map.prototype.forEach requires a callback function.");
|
|
24991
|
-
}
|
|
24992
|
-
const cursor = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
|
|
24993
|
-
try {
|
|
24994
|
-
for (let entry = cursor.next(); !entry.done; entry = cursor.next()) {
|
|
24995
|
-
const key = entry.value;
|
|
24996
|
-
const value = target.entries.get(key);
|
|
24997
|
-
await options.callClosure(callback, [value, key, target], stack, args[1]);
|
|
24998
|
-
}
|
|
24999
|
-
} finally {
|
|
25000
|
-
cursor.leave();
|
|
25001
|
-
}
|
|
25002
|
-
return void 0;
|
|
25003
|
-
}
|
|
25004
|
-
case "keys":
|
|
25005
|
-
case "values":
|
|
25006
|
-
case "entries":
|
|
25007
|
-
return createSandboxCollectionIterator(target, methodName);
|
|
25008
|
-
}
|
|
25009
|
-
}
|
|
25010
|
-
|
|
25011
|
-
// packages/safe-js/src/interp/methods/number.ts
|
|
25012
|
-
var numberMethodNames = /* @__PURE__ */ new Set([
|
|
25013
|
-
"toExponential",
|
|
25014
|
-
"toFixed",
|
|
25015
|
-
"toPrecision",
|
|
25016
|
-
"toString"
|
|
25017
|
-
]);
|
|
25018
|
-
function getNumberMember(property, budget) {
|
|
25019
|
-
if (!isNumberMethodName(property)) {
|
|
25020
|
-
return void 0;
|
|
25021
|
-
}
|
|
25022
|
-
return createSandboxClosure({
|
|
25023
|
-
sandbox: true,
|
|
25024
|
-
name: `Number#${property}`,
|
|
25025
|
-
call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
|
|
25026
|
-
});
|
|
25027
|
-
}
|
|
25028
|
-
function isNumberMethodName(property) {
|
|
25029
|
-
return typeof property === "string" && numberMethodNames.has(property);
|
|
25030
|
-
}
|
|
25031
|
-
function callNumberMethod(value, methodName, args, budget, context) {
|
|
25032
|
-
if (typeof value !== "number") {
|
|
25033
|
-
throw new TypeError(`Number#${methodName} requires a number receiver.`);
|
|
25034
|
-
}
|
|
25035
|
-
const argument = args[0];
|
|
25036
|
-
if (argument !== null && typeof argument === "object") {
|
|
25037
|
-
return formatObjectArgument(value, methodName, argument, budget, context);
|
|
25038
|
-
}
|
|
25039
|
-
return formatNumber(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
|
|
25040
|
-
}
|
|
25041
|
-
async function formatObjectArgument(value, methodName, argument, budget, context) {
|
|
25042
|
-
const retainedArgument = {};
|
|
25043
|
-
budget.setRetainedValues(retainedArgument, () => [argument]);
|
|
25044
|
-
try {
|
|
25045
|
-
const number = await sandboxNumber(argument, budget, context);
|
|
25046
|
-
return formatNumber(value, methodName, number, budget);
|
|
25047
|
-
} finally {
|
|
25048
|
-
budget.setRetainedValues(retainedArgument, void 0);
|
|
25049
|
-
}
|
|
25050
|
-
}
|
|
25051
|
-
function formatNumber(value, methodName, argument, budget) {
|
|
25052
|
-
let result;
|
|
25053
|
-
try {
|
|
25054
|
-
result = value[methodName](argument);
|
|
25055
|
-
} catch (error) {
|
|
25056
|
-
if (!(error instanceof RangeError)) throw error;
|
|
25057
|
-
const detail = methodName === "toString" ? "radix must be between 2 and 36." : methodName === "toPrecision" ? "precision must be between 1 and 100." : "digits must be between 0 and 100.";
|
|
25058
|
-
throw new RangeError(`Number#${methodName} ${detail}`);
|
|
25059
|
-
}
|
|
25060
|
-
return budget.allocateString(result);
|
|
25061
|
-
}
|
|
25062
|
-
|
|
25063
|
-
// packages/safe-js/src/interp/methods/generator.ts
|
|
25064
|
-
var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
|
|
25065
|
-
function getGeneratorMember(target, property, budget) {
|
|
25066
|
-
if (typeof property !== "string" || !generatorMethodNames.has(property)) {
|
|
25067
|
-
return void 0;
|
|
25068
|
-
}
|
|
25069
|
-
return createSandboxClosure({
|
|
25070
|
-
sandbox: true,
|
|
25071
|
-
name: property,
|
|
25072
|
-
call: async ([value]) => {
|
|
25073
|
-
const iterator = getSandboxIterator(target);
|
|
25074
|
-
const result = await iterator[property](value);
|
|
25075
|
-
return allocateProducedSandboxValue(
|
|
25076
|
-
{ value: result.value, done: result.done === true },
|
|
25077
|
-
budget
|
|
25078
|
-
);
|
|
25079
|
-
}
|
|
25080
|
-
});
|
|
25081
|
-
}
|
|
25082
|
-
|
|
25083
|
-
// packages/safe-js/src/interp/methods/string.ts
|
|
25084
|
-
var SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
|
|
25085
|
-
var stringMethodNames = /* @__PURE__ */ new Set([
|
|
25086
|
-
"at",
|
|
25087
|
-
"charAt",
|
|
25088
|
-
"charCodeAt",
|
|
25089
|
-
"codePointAt",
|
|
25090
|
-
"concat",
|
|
25091
|
-
"endsWith",
|
|
25092
|
-
"includes",
|
|
25093
|
-
"indexOf",
|
|
25094
|
-
"isWellFormed",
|
|
25095
|
-
"lastIndexOf",
|
|
25096
|
-
"localeCompare",
|
|
25097
|
-
"match",
|
|
25098
|
-
"matchAll",
|
|
25099
|
-
"normalize",
|
|
25100
|
-
"padEnd",
|
|
25101
|
-
"padStart",
|
|
25102
|
-
"repeat",
|
|
25103
|
-
"replace",
|
|
25104
|
-
"replaceAll",
|
|
25105
|
-
"slice",
|
|
25106
|
-
"search",
|
|
25107
|
-
"split",
|
|
25108
|
-
"startsWith",
|
|
25109
|
-
"substr",
|
|
25110
|
-
"substring",
|
|
25111
|
-
"toLowerCase",
|
|
25112
|
-
"toUpperCase",
|
|
25113
|
-
"toWellFormed",
|
|
25114
|
-
"trim",
|
|
25115
|
-
"trimEnd",
|
|
25116
|
-
"trimStart"
|
|
25117
|
-
]);
|
|
25118
|
-
function getStringMember(value, property, budget) {
|
|
25119
|
-
const index = getStringIndex(property);
|
|
25120
|
-
if (index !== void 0) {
|
|
25121
|
-
return value[index];
|
|
25122
|
-
}
|
|
25123
|
-
if (property === "length") {
|
|
25124
|
-
return value.length;
|
|
25125
|
-
}
|
|
25126
|
-
if (!isStringMethodName(property)) {
|
|
25127
|
-
return void 0;
|
|
25128
|
-
}
|
|
25129
|
-
return createSandboxClosure({
|
|
25130
|
-
sandbox: true,
|
|
25131
|
-
name: `String#${property}`,
|
|
25132
|
-
...property === "localeCompare" ? { length: 1 } : {},
|
|
25133
|
-
...property === "isWellFormed" || property === "toWellFormed" ? { length: 0 } : {},
|
|
25134
|
-
call: async (args, context) => {
|
|
25173
|
+
name: `String#${property}`,
|
|
25174
|
+
...property === "localeCompare" ? { length: 1 } : {},
|
|
25175
|
+
...property === "isWellFormed" || property === "toWellFormed" ? { length: 0 } : {},
|
|
25176
|
+
call: async (args, context) => {
|
|
25135
25177
|
const receiver = context?.thisValue;
|
|
25136
25178
|
if (receiver === null || receiver === void 0) {
|
|
25137
25179
|
throw new TypeError(`String#${property} requires a non-null receiver.`);
|
|
@@ -25559,30 +25601,246 @@ function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
|
|
|
25559
25601
|
if (methodName === "match" && matches.length === 0) return null;
|
|
25560
25602
|
return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
|
|
25561
25603
|
}
|
|
25562
|
-
function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
|
|
25563
|
-
const matches = [];
|
|
25564
|
-
do {
|
|
25565
|
-
const match = executeRegex(regex, value, lastIndex);
|
|
25566
|
-
if (match === null) break;
|
|
25567
|
-
budget?.allocateArrayLength(matches.length + 1);
|
|
25568
|
-
matches.push(match);
|
|
25569
|
-
lastIndex = match.index + match.text.length;
|
|
25570
|
-
if (all && match.text.length === 0) regex.lastIndex = ++lastIndex;
|
|
25571
|
-
} while (all);
|
|
25572
|
-
return matches;
|
|
25604
|
+
function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
|
|
25605
|
+
const matches = [];
|
|
25606
|
+
do {
|
|
25607
|
+
const match = executeRegex(regex, value, lastIndex);
|
|
25608
|
+
if (match === null) break;
|
|
25609
|
+
budget?.allocateArrayLength(matches.length + 1);
|
|
25610
|
+
matches.push(match);
|
|
25611
|
+
lastIndex = match.index + match.text.length;
|
|
25612
|
+
if (all && match.text.length === 0) regex.lastIndex = ++lastIndex;
|
|
25613
|
+
} while (all);
|
|
25614
|
+
return matches;
|
|
25615
|
+
}
|
|
25616
|
+
function splitString(value, separator, limit) {
|
|
25617
|
+
const split = String.prototype.split;
|
|
25618
|
+
return split.call(value, separator, limit);
|
|
25619
|
+
}
|
|
25620
|
+
function asNumber(value) {
|
|
25621
|
+
return Number(value);
|
|
25622
|
+
}
|
|
25623
|
+
function asNumberOrUndefined(value) {
|
|
25624
|
+
return value === void 0 ? void 0 : Number(value);
|
|
25625
|
+
}
|
|
25626
|
+
function asStringOrUndefined(value) {
|
|
25627
|
+
return value === void 0 ? void 0 : String(value);
|
|
25628
|
+
}
|
|
25629
|
+
|
|
25630
|
+
// packages/safe-js/src/interp/methods/collection-callback.ts
|
|
25631
|
+
var activeCallbacks = /* @__PURE__ */ new WeakMap();
|
|
25632
|
+
function enterKeyedCollectionCallback(target, keys, budget) {
|
|
25633
|
+
let state = activeCallbacks.get(target);
|
|
25634
|
+
if (state === void 0) {
|
|
25635
|
+
state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
|
|
25636
|
+
activeCallbacks.set(target, state);
|
|
25637
|
+
}
|
|
25638
|
+
const cursor = { budget, pending: /* @__PURE__ */ new Set() };
|
|
25639
|
+
state.cursors.add(cursor);
|
|
25640
|
+
const leave = () => {
|
|
25641
|
+
if (!state.cursors.delete(cursor)) return;
|
|
25642
|
+
cursor.pending.clear();
|
|
25643
|
+
budget.setRetainedDataUsage(cursor, 0);
|
|
25644
|
+
budget.setRetainedValues(cursor, void 0);
|
|
25645
|
+
if (state.cursors.size === 0) {
|
|
25646
|
+
activeCallbacks.delete(target);
|
|
25647
|
+
state.leaveRunning();
|
|
25648
|
+
}
|
|
25649
|
+
};
|
|
25650
|
+
try {
|
|
25651
|
+
budget.setRetainedDataUsage(cursor, 1);
|
|
25652
|
+
budget.setRetainedValues(cursor, () => cursor.pending);
|
|
25653
|
+
for (const key of keys) updatePendingKeys(cursor, "add", key);
|
|
25654
|
+
} catch (error) {
|
|
25655
|
+
leave();
|
|
25656
|
+
throw error;
|
|
25657
|
+
}
|
|
25658
|
+
return {
|
|
25659
|
+
next: () => {
|
|
25660
|
+
budget.visitNode();
|
|
25661
|
+
for (const key of cursor.pending) {
|
|
25662
|
+
cursor.pending.delete(key);
|
|
25663
|
+
budget.setRetainedDataUsage(cursor, 1 + cursor.pending.size);
|
|
25664
|
+
return { done: false, value: key };
|
|
25665
|
+
}
|
|
25666
|
+
return { done: true, value: void 0 };
|
|
25667
|
+
},
|
|
25668
|
+
leave
|
|
25669
|
+
};
|
|
25670
|
+
}
|
|
25671
|
+
function updateKeyedCollectionCallbacks(target, mutation, key) {
|
|
25672
|
+
const state = activeCallbacks.get(target);
|
|
25673
|
+
if (state === void 0) return;
|
|
25674
|
+
for (const cursor of state.cursors) updatePendingKeys(cursor, mutation, key);
|
|
25675
|
+
}
|
|
25676
|
+
function updatePendingKeys(cursor, mutation, key) {
|
|
25677
|
+
const { budget, pending } = cursor;
|
|
25678
|
+
budget.visitNode();
|
|
25679
|
+
if (mutation === "add") {
|
|
25680
|
+
const nextSize = pending.has(key) ? pending.size : pending.size + 1;
|
|
25681
|
+
budget.allocateCollectionEntries(nextSize);
|
|
25682
|
+
budget.setRetainedDataUsage(cursor, 1 + nextSize);
|
|
25683
|
+
pending.add(key);
|
|
25684
|
+
} else {
|
|
25685
|
+
if (mutation === "delete") pending.delete(key);
|
|
25686
|
+
else pending.clear();
|
|
25687
|
+
budget.setRetainedDataUsage(cursor, 1 + pending.size);
|
|
25688
|
+
}
|
|
25689
|
+
}
|
|
25690
|
+
|
|
25691
|
+
// packages/safe-js/src/interp/methods/map.ts
|
|
25692
|
+
var mapMethodNames = /* @__PURE__ */ new Set([
|
|
25693
|
+
"get",
|
|
25694
|
+
"set",
|
|
25695
|
+
"has",
|
|
25696
|
+
"delete",
|
|
25697
|
+
"clear",
|
|
25698
|
+
"forEach",
|
|
25699
|
+
"keys",
|
|
25700
|
+
"values",
|
|
25701
|
+
"entries"
|
|
25702
|
+
]);
|
|
25703
|
+
function isMapMethodName(value) {
|
|
25704
|
+
return typeof value === "string" && mapMethodNames.has(value);
|
|
25705
|
+
}
|
|
25706
|
+
function getMapMember(target, property, options) {
|
|
25707
|
+
if (property === "size") {
|
|
25708
|
+
return target.entries.size;
|
|
25709
|
+
}
|
|
25710
|
+
if (!isMapMethodName(property)) {
|
|
25711
|
+
return void 0;
|
|
25712
|
+
}
|
|
25713
|
+
return createSandboxClosure({
|
|
25714
|
+
sandbox: true,
|
|
25715
|
+
call: (args, context) => {
|
|
25716
|
+
const receiver = context?.thisValue;
|
|
25717
|
+
if (!isSandboxMap(receiver)) throw new TypeError(`Map#${property} requires a Map receiver.`);
|
|
25718
|
+
return callMapMethod(receiver, property, args, options, context?.stack ?? []);
|
|
25719
|
+
},
|
|
25720
|
+
name: property
|
|
25721
|
+
});
|
|
25722
|
+
}
|
|
25723
|
+
async function callMapMethod(target, methodName, args, options, stack = []) {
|
|
25724
|
+
switch (methodName) {
|
|
25725
|
+
case "get":
|
|
25726
|
+
return target.entries.get(args[0]);
|
|
25727
|
+
case "set": {
|
|
25728
|
+
assertCollectionMutable(target);
|
|
25729
|
+
const exists = target.entries.has(args[0]);
|
|
25730
|
+
const nextSize = exists ? target.entries.size : target.entries.size + 1;
|
|
25731
|
+
options.budget.allocateCollectionEntries(nextSize);
|
|
25732
|
+
if (!exists) updateKeyedCollectionCallbacks(target, "add", args[0]);
|
|
25733
|
+
target.entries.set(args[0], args[1]);
|
|
25734
|
+
return target;
|
|
25735
|
+
}
|
|
25736
|
+
case "has":
|
|
25737
|
+
return target.entries.has(args[0]);
|
|
25738
|
+
case "delete": {
|
|
25739
|
+
assertCollectionMutable(target);
|
|
25740
|
+
const deleted = target.entries.delete(args[0]);
|
|
25741
|
+
if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
|
|
25742
|
+
return deleted;
|
|
25743
|
+
}
|
|
25744
|
+
case "clear":
|
|
25745
|
+
assertCollectionMutable(target);
|
|
25746
|
+
target.entries.clear();
|
|
25747
|
+
updateKeyedCollectionCallbacks(target, "clear");
|
|
25748
|
+
return void 0;
|
|
25749
|
+
case "forEach": {
|
|
25750
|
+
const callback = args[0];
|
|
25751
|
+
if (!isSandboxClosure(callback)) {
|
|
25752
|
+
throw new TypeError("Map.prototype.forEach requires a callback function.");
|
|
25753
|
+
}
|
|
25754
|
+
const cursor = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
|
|
25755
|
+
try {
|
|
25756
|
+
for (let entry = cursor.next(); !entry.done; entry = cursor.next()) {
|
|
25757
|
+
const key = entry.value;
|
|
25758
|
+
const value = target.entries.get(key);
|
|
25759
|
+
await options.callClosure(callback, [value, key, target], stack, args[1]);
|
|
25760
|
+
}
|
|
25761
|
+
} finally {
|
|
25762
|
+
cursor.leave();
|
|
25763
|
+
}
|
|
25764
|
+
return void 0;
|
|
25765
|
+
}
|
|
25766
|
+
case "keys":
|
|
25767
|
+
case "values":
|
|
25768
|
+
case "entries":
|
|
25769
|
+
return createSandboxCollectionIterator(target, methodName);
|
|
25770
|
+
}
|
|
25771
|
+
}
|
|
25772
|
+
|
|
25773
|
+
// packages/safe-js/src/interp/methods/number.ts
|
|
25774
|
+
var numberMethodNames = /* @__PURE__ */ new Set([
|
|
25775
|
+
"toExponential",
|
|
25776
|
+
"toFixed",
|
|
25777
|
+
"toPrecision",
|
|
25778
|
+
"toString"
|
|
25779
|
+
]);
|
|
25780
|
+
function getNumberMember(property, budget) {
|
|
25781
|
+
if (!isNumberMethodName(property)) {
|
|
25782
|
+
return void 0;
|
|
25783
|
+
}
|
|
25784
|
+
return createSandboxClosure({
|
|
25785
|
+
sandbox: true,
|
|
25786
|
+
name: `Number#${property}`,
|
|
25787
|
+
call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
|
|
25788
|
+
});
|
|
25789
|
+
}
|
|
25790
|
+
function isNumberMethodName(property) {
|
|
25791
|
+
return typeof property === "string" && numberMethodNames.has(property);
|
|
25573
25792
|
}
|
|
25574
|
-
function
|
|
25575
|
-
|
|
25576
|
-
|
|
25793
|
+
function callNumberMethod(value, methodName, args, budget, context) {
|
|
25794
|
+
if (isSandboxBox(value)) value = boxedValue(value);
|
|
25795
|
+
if (typeof value !== "number") {
|
|
25796
|
+
throw new TypeError(`Number#${methodName} requires a number receiver.`);
|
|
25797
|
+
}
|
|
25798
|
+
const argument = args[0];
|
|
25799
|
+
if (argument !== null && typeof argument === "object") {
|
|
25800
|
+
return formatObjectArgument(value, methodName, argument, budget, context);
|
|
25801
|
+
}
|
|
25802
|
+
return formatNumber(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
|
|
25577
25803
|
}
|
|
25578
|
-
function
|
|
25579
|
-
|
|
25804
|
+
async function formatObjectArgument(value, methodName, argument, budget, context) {
|
|
25805
|
+
const retainedArgument = {};
|
|
25806
|
+
budget.setRetainedValues(retainedArgument, () => [argument]);
|
|
25807
|
+
try {
|
|
25808
|
+
const number = await sandboxNumber(argument, budget, context);
|
|
25809
|
+
return formatNumber(value, methodName, number, budget);
|
|
25810
|
+
} finally {
|
|
25811
|
+
budget.setRetainedValues(retainedArgument, void 0);
|
|
25812
|
+
}
|
|
25580
25813
|
}
|
|
25581
|
-
function
|
|
25582
|
-
|
|
25814
|
+
function formatNumber(value, methodName, argument, budget) {
|
|
25815
|
+
let result;
|
|
25816
|
+
try {
|
|
25817
|
+
result = value[methodName](argument);
|
|
25818
|
+
} catch (error) {
|
|
25819
|
+
if (!(error instanceof RangeError)) throw error;
|
|
25820
|
+
const detail = methodName === "toString" ? "radix must be between 2 and 36." : methodName === "toPrecision" ? "precision must be between 1 and 100." : "digits must be between 0 and 100.";
|
|
25821
|
+
throw new RangeError(`Number#${methodName} ${detail}`);
|
|
25822
|
+
}
|
|
25823
|
+
return budget.allocateString(result);
|
|
25583
25824
|
}
|
|
25584
|
-
|
|
25585
|
-
|
|
25825
|
+
|
|
25826
|
+
// packages/safe-js/src/interp/methods/generator.ts
|
|
25827
|
+
var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
|
|
25828
|
+
function getGeneratorMember(target, property, budget) {
|
|
25829
|
+
if (typeof property !== "string" || !generatorMethodNames.has(property)) {
|
|
25830
|
+
return void 0;
|
|
25831
|
+
}
|
|
25832
|
+
return createSandboxClosure({
|
|
25833
|
+
sandbox: true,
|
|
25834
|
+
name: property,
|
|
25835
|
+
call: async ([value]) => {
|
|
25836
|
+
const iterator = getSandboxIterator(target);
|
|
25837
|
+
const result = await iterator[property](value);
|
|
25838
|
+
return allocateProducedSandboxValue(
|
|
25839
|
+
{ value: result.value, done: result.done === true },
|
|
25840
|
+
budget
|
|
25841
|
+
);
|
|
25842
|
+
}
|
|
25843
|
+
});
|
|
25586
25844
|
}
|
|
25587
25845
|
|
|
25588
25846
|
// packages/safe-js/src/interp/methods/set.ts
|
|
@@ -25719,7 +25977,11 @@ function createObjectGlobal(methods, budget) {
|
|
|
25719
25977
|
budget.chargeDataUsage(1);
|
|
25720
25978
|
return /* @__PURE__ */ Object.create(null);
|
|
25721
25979
|
}
|
|
25722
|
-
if (typeof value !== "object")
|
|
25980
|
+
if (typeof value !== "object") {
|
|
25981
|
+
const box = createSandboxBox(value);
|
|
25982
|
+
budget.chargeDataUsage(measureSandboxData([box]));
|
|
25983
|
+
return box;
|
|
25984
|
+
}
|
|
25723
25985
|
return value;
|
|
25724
25986
|
};
|
|
25725
25987
|
const constructor = createSandboxClosure({
|
|
@@ -25749,9 +26011,7 @@ function createObjectGlobal(methods, budget) {
|
|
|
25749
26011
|
length: 0,
|
|
25750
26012
|
call: (_args, context) => {
|
|
25751
26013
|
const value = requireReceiver(context?.thisValue);
|
|
25752
|
-
|
|
25753
|
-
throw new TypeError("Object primitive boxing is not supported.");
|
|
25754
|
-
return value;
|
|
26014
|
+
return construct([value]);
|
|
25755
26015
|
}
|
|
25756
26016
|
}),
|
|
25757
26017
|
hasOwnProperty: createSandboxClosure({
|
|
@@ -25819,6 +26079,7 @@ function hasOwnSandboxProperty(value, key, enumerable) {
|
|
|
25819
26079
|
return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
|
|
25820
26080
|
}
|
|
25821
26081
|
function typeTag(value) {
|
|
26082
|
+
if (isSandboxBox(value)) value = boxedValue(value);
|
|
25822
26083
|
if (value === void 0) return "Undefined";
|
|
25823
26084
|
if (value === null) return "Null";
|
|
25824
26085
|
if (typeof value === "string") return "String";
|
|
@@ -25923,12 +26184,12 @@ function isSandboxSetConstructor(value) {
|
|
|
25923
26184
|
function populateCollection(source, collection, { name, budget, context, append, retainedValues }) {
|
|
25924
26185
|
budget.allocateCollectionEntries(0);
|
|
25925
26186
|
if (source === void 0 || source === null) return collection;
|
|
25926
|
-
const iterator = getSandboxIterator(source, budget);
|
|
26187
|
+
const iterator = getSandboxIterator(source, budget, context);
|
|
25927
26188
|
if (iterator === void 0) throw new TypeError(`${name} constructor requires an iterable.`);
|
|
25928
26189
|
let entry;
|
|
25929
26190
|
let failure;
|
|
25930
26191
|
const retained = {};
|
|
25931
|
-
budget.setRetainedValues(retained, () => [source, collection, entry, failure, ...retainedValues?.() ?? []]);
|
|
26192
|
+
budget.setRetainedValues(retained, () => [source, iterator.retainedValue, collection, entry, failure, ...retainedValues?.() ?? []]);
|
|
25932
26193
|
const checkData = createDataCheckpoint(budget, context);
|
|
25933
26194
|
const closeOnThrow = (error) => {
|
|
25934
26195
|
failure = isCapturedException(error) ? error.reason : error;
|
|
@@ -25938,7 +26199,7 @@ function populateCollection(source, collection, { name, budget, context, append,
|
|
|
25938
26199
|
};
|
|
25939
26200
|
try {
|
|
25940
26201
|
const closing = iterator.return?.();
|
|
25941
|
-
if (iterator.generator) return Promise.resolve(closing).then(() => {
|
|
26202
|
+
if (iterator.generator || iterator.asynchronous) return Promise.resolve(closing).then(() => {
|
|
25942
26203
|
throw error;
|
|
25943
26204
|
}, rethrow);
|
|
25944
26205
|
} catch (closeError) {
|
|
@@ -25960,7 +26221,7 @@ function populateCollection(source, collection, { name, budget, context, append,
|
|
|
25960
26221
|
}
|
|
25961
26222
|
return false;
|
|
25962
26223
|
};
|
|
25963
|
-
if (iterator.generator) {
|
|
26224
|
+
if (iterator.generator || iterator.asynchronous) {
|
|
25964
26225
|
return (async () => {
|
|
25965
26226
|
try {
|
|
25966
26227
|
checkData(collection, 0, true);
|
|
@@ -26915,22 +27176,29 @@ async function evaluateBinaryExpression(node, context) {
|
|
|
26915
27176
|
if (left.kind !== "normal") {
|
|
26916
27177
|
return left;
|
|
26917
27178
|
}
|
|
27179
|
+
let leftValue = left.value;
|
|
26918
27180
|
let rightValue;
|
|
26919
|
-
const release = retainValues(context.budget, () => [
|
|
27181
|
+
const release = retainValues(context.budget, () => [leftValue, rightValue]);
|
|
26920
27182
|
try {
|
|
26921
27183
|
const right = await evaluateNode(node.right, context);
|
|
26922
27184
|
if (right.kind !== "normal") {
|
|
26923
27185
|
return right;
|
|
26924
27186
|
}
|
|
26925
27187
|
rightValue = right.value;
|
|
26926
|
-
let leftValue = left.value;
|
|
26927
27188
|
if (node.operator === "in") {
|
|
26928
27189
|
if (typeof right.value !== "object" || right.value === null) {
|
|
26929
27190
|
throw new TypeError("Right-hand side of 'in' must be an object.");
|
|
26930
27191
|
}
|
|
26931
27192
|
leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
|
|
26932
27193
|
}
|
|
26933
|
-
|
|
27194
|
+
if (!["in", "instanceof", "===", "!=="].includes(node.operator)) {
|
|
27195
|
+
const equality = node.operator === "==" || node.operator === "!=";
|
|
27196
|
+
if (isSandboxBox(leftValue) && (!equality || rightValue !== null && rightValue !== void 0 && typeof rightValue !== "object"))
|
|
27197
|
+
leftValue = await toNumericPrimitive(leftValue, context);
|
|
27198
|
+
if (isSandboxBox(rightValue) && (!equality || left.value !== null && left.value !== void 0 && typeof left.value !== "object"))
|
|
27199
|
+
rightValue = await toNumericPrimitive(rightValue, context);
|
|
27200
|
+
}
|
|
27201
|
+
const value = applyBinaryOperator(node, leftValue, rightValue, context);
|
|
26934
27202
|
return {
|
|
26935
27203
|
kind: "normal",
|
|
26936
27204
|
hasValue: true,
|
|
@@ -27518,63 +27786,68 @@ async function evaluateForOfStatement(node, context) {
|
|
|
27518
27786
|
};
|
|
27519
27787
|
}
|
|
27520
27788
|
async function evaluateForOfIterator(node, value, context, restoredEntry) {
|
|
27521
|
-
const iterator = getSandboxIterator(value, context.budget);
|
|
27789
|
+
const iterator = getSandboxIterator(value, context.budget, createCoercionContext(context));
|
|
27522
27790
|
if (iterator === void 0) {
|
|
27523
27791
|
throw new TypeError(`${String(value)} is not a supported iterable`);
|
|
27524
27792
|
}
|
|
27525
|
-
const
|
|
27526
|
-
|
|
27527
|
-
|
|
27528
|
-
|
|
27529
|
-
|
|
27530
|
-
|
|
27531
|
-
|
|
27532
|
-
|
|
27533
|
-
|
|
27534
|
-
|
|
27535
|
-
|
|
27536
|
-
while (true) {
|
|
27537
|
-
const iteration = restoredEntry ?? await iterator.next();
|
|
27538
|
-
restoredEntry = void 0;
|
|
27539
|
-
if (typeof iteration !== "object" || iteration === null) {
|
|
27540
|
-
throw new TypeError("Iterator result must be an object.");
|
|
27541
|
-
}
|
|
27542
|
-
if (iteration.done) {
|
|
27543
|
-
context.activeLoopIterations.delete(nodeId);
|
|
27544
|
-
return normalEmptyResult();
|
|
27545
|
-
}
|
|
27546
|
-
context.activeLoopIterations.set(
|
|
27547
|
-
nodeId,
|
|
27548
|
-
iterator.snapshotIndex === void 0 ? index : {
|
|
27549
|
-
get index() {
|
|
27550
|
-
return iterator.snapshotIndex();
|
|
27551
|
-
},
|
|
27552
|
-
values: [value, iteration.value]
|
|
27793
|
+
const releaseIterator = retainValues(context.budget, () => [value, iterator.retainedValue]);
|
|
27794
|
+
try {
|
|
27795
|
+
const nodeId = node.nodeId ?? -1;
|
|
27796
|
+
let index = consumeRestoredLoopIterationIndex(node, context);
|
|
27797
|
+
for (let skipped = 0; skipped < index; skipped += 1) {
|
|
27798
|
+
const skippedIteration = await iterator.next();
|
|
27799
|
+
if (typeof skippedIteration !== "object" || skippedIteration === null) {
|
|
27800
|
+
throw new TypeError("Iterator result must be an object.");
|
|
27801
|
+
}
|
|
27802
|
+
if (skippedIteration.done) {
|
|
27803
|
+
return normalEmptyResult();
|
|
27553
27804
|
}
|
|
27554
|
-
);
|
|
27555
|
-
const scope = context.scope.child();
|
|
27556
|
-
const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
|
|
27557
|
-
if (!binding.ok) {
|
|
27558
|
-
return binding.result;
|
|
27559
|
-
}
|
|
27560
|
-
const iterationContext = createLoopIterationContext(context, scope);
|
|
27561
|
-
emitLoopIterationBreakpoint(node, iterationContext);
|
|
27562
|
-
const result = await evaluateNode(node.body, iterationContext);
|
|
27563
|
-
if (isMatchingBreak(result, loopLabels(node))) {
|
|
27564
|
-
context.activeLoopIterations.delete(nodeId);
|
|
27565
|
-
await closeIterator(iterator);
|
|
27566
|
-
return normalEmptyResult();
|
|
27567
27805
|
}
|
|
27568
|
-
|
|
27806
|
+
while (true) {
|
|
27807
|
+
const iteration = restoredEntry ?? await iterator.next();
|
|
27808
|
+
restoredEntry = void 0;
|
|
27809
|
+
if (typeof iteration !== "object" || iteration === null) {
|
|
27810
|
+
throw new TypeError("Iterator result must be an object.");
|
|
27811
|
+
}
|
|
27812
|
+
if (iteration.done) {
|
|
27813
|
+
context.activeLoopIterations.delete(nodeId);
|
|
27814
|
+
return normalEmptyResult();
|
|
27815
|
+
}
|
|
27816
|
+
context.activeLoopIterations.set(
|
|
27817
|
+
nodeId,
|
|
27818
|
+
iterator.snapshotIndex === void 0 ? index : {
|
|
27819
|
+
get index() {
|
|
27820
|
+
return iterator.snapshotIndex();
|
|
27821
|
+
},
|
|
27822
|
+
values: [value, iteration.value]
|
|
27823
|
+
}
|
|
27824
|
+
);
|
|
27825
|
+
const scope = context.scope.child();
|
|
27826
|
+
const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
|
|
27827
|
+
if (!binding.ok) {
|
|
27828
|
+
return binding.result;
|
|
27829
|
+
}
|
|
27830
|
+
const iterationContext = createLoopIterationContext(context, scope);
|
|
27831
|
+
emitLoopIterationBreakpoint(node, iterationContext);
|
|
27832
|
+
const result = await evaluateNode(node.body, iterationContext);
|
|
27833
|
+
if (isMatchingBreak(result, loopLabels(node))) {
|
|
27834
|
+
context.activeLoopIterations.delete(nodeId);
|
|
27835
|
+
await closeIterator(iterator);
|
|
27836
|
+
return normalEmptyResult();
|
|
27837
|
+
}
|
|
27838
|
+
if (isMatchingContinue(result, loopLabels(node))) {
|
|
27839
|
+
index += 1;
|
|
27840
|
+
continue;
|
|
27841
|
+
}
|
|
27842
|
+
if (result.kind !== "normal") {
|
|
27843
|
+
context.activeLoopIterations.delete(nodeId);
|
|
27844
|
+
await closeIterator(iterator);
|
|
27845
|
+
return result;
|
|
27846
|
+
}
|
|
27569
27847
|
index += 1;
|
|
27570
|
-
continue;
|
|
27571
|
-
}
|
|
27572
|
-
if (result.kind !== "normal") {
|
|
27573
|
-
context.activeLoopIterations.delete(nodeId);
|
|
27574
|
-
await closeIterator(iterator);
|
|
27575
|
-
return result;
|
|
27576
27848
|
}
|
|
27577
|
-
|
|
27849
|
+
} finally {
|
|
27850
|
+
releaseIterator();
|
|
27578
27851
|
}
|
|
27579
27852
|
}
|
|
27580
27853
|
async function evaluateForInStatement(node, context) {
|
|
@@ -27944,52 +28217,64 @@ async function evaluateYieldDelegate(node, context) {
|
|
|
27944
28217
|
if (argument.kind !== "normal") {
|
|
27945
28218
|
return argument;
|
|
27946
28219
|
}
|
|
27947
|
-
const iterator = getSandboxIterator(
|
|
28220
|
+
const iterator = getSandboxIterator(
|
|
28221
|
+
argument.value,
|
|
28222
|
+
context.budget,
|
|
28223
|
+
createCoercionContext(context)
|
|
28224
|
+
);
|
|
27948
28225
|
if (iterator === void 0) {
|
|
27949
28226
|
throw new TypeError(`${String(argument.value)} is not a supported iterable`);
|
|
27950
28227
|
}
|
|
27951
|
-
|
|
27952
|
-
|
|
27953
|
-
|
|
27954
|
-
|
|
27955
|
-
|
|
27956
|
-
|
|
27957
|
-
|
|
27958
|
-
|
|
27959
|
-
|
|
27960
|
-
|
|
27961
|
-
|
|
27962
|
-
|
|
28228
|
+
const releaseIterator = retainValues(context.budget, () => [
|
|
28229
|
+
argument.value,
|
|
28230
|
+
iterator.retainedValue
|
|
28231
|
+
]);
|
|
28232
|
+
try {
|
|
28233
|
+
let completion = {
|
|
28234
|
+
type: "normal",
|
|
28235
|
+
value: void 0
|
|
28236
|
+
};
|
|
28237
|
+
const replay = context.generatorResume?.sent ?? [];
|
|
28238
|
+
let replayIndex = 0;
|
|
28239
|
+
while (true) {
|
|
28240
|
+
const method = completion.type === "normal" ? "next" : completion.type;
|
|
28241
|
+
const iteratorMethod = iterator[method];
|
|
28242
|
+
if (iteratorMethod === void 0) {
|
|
28243
|
+
if (completion.type === "throw") {
|
|
28244
|
+
throw completion.value;
|
|
28245
|
+
}
|
|
28246
|
+
return generatorCompletionResult(completion);
|
|
27963
28247
|
}
|
|
27964
|
-
|
|
27965
|
-
|
|
27966
|
-
|
|
27967
|
-
|
|
27968
|
-
|
|
27969
|
-
return
|
|
28248
|
+
const result = await iteratorMethod(completion.value);
|
|
28249
|
+
if (result.done) {
|
|
28250
|
+
if (completion.type === "return") {
|
|
28251
|
+
return generatorCompletionResult({ type: "return", value: result.value });
|
|
28252
|
+
}
|
|
28253
|
+
return {
|
|
28254
|
+
kind: "normal",
|
|
28255
|
+
hasValue: true,
|
|
28256
|
+
value: result.value
|
|
28257
|
+
};
|
|
27970
28258
|
}
|
|
27971
|
-
|
|
27972
|
-
|
|
27973
|
-
|
|
27974
|
-
|
|
27975
|
-
}
|
|
27976
|
-
|
|
27977
|
-
|
|
27978
|
-
|
|
27979
|
-
|
|
27980
|
-
|
|
28259
|
+
if (replayIndex < replay.length - 1) {
|
|
28260
|
+
completion = replay[replayIndex + 1];
|
|
28261
|
+
replayIndex += 1;
|
|
28262
|
+
continue;
|
|
28263
|
+
}
|
|
28264
|
+
const completionPromise = context.generatorYield(
|
|
28265
|
+
allocateProducedSandboxValue(result.value, context.budget),
|
|
28266
|
+
node.nodeId
|
|
28267
|
+
);
|
|
28268
|
+
emitResumeBreakpoint(context, {
|
|
28269
|
+
kind: "generator-yield",
|
|
28270
|
+
nodeId: node.nodeId,
|
|
28271
|
+
span: node.span
|
|
28272
|
+
});
|
|
28273
|
+
completion = await completionPromise;
|
|
28274
|
+
context.generatorResume = void 0;
|
|
27981
28275
|
}
|
|
27982
|
-
|
|
27983
|
-
|
|
27984
|
-
node.nodeId
|
|
27985
|
-
);
|
|
27986
|
-
emitResumeBreakpoint(context, {
|
|
27987
|
-
kind: "generator-yield",
|
|
27988
|
-
nodeId: node.nodeId,
|
|
27989
|
-
span: node.span
|
|
27990
|
-
});
|
|
27991
|
-
completion = await completionPromise;
|
|
27992
|
-
context.generatorResume = void 0;
|
|
28276
|
+
} finally {
|
|
28277
|
+
releaseIterator();
|
|
27993
28278
|
}
|
|
27994
28279
|
}
|
|
27995
28280
|
function generatorCompletionResult(completion) {
|
|
@@ -28136,6 +28421,14 @@ async function evaluateMemberExpression(node, context) {
|
|
|
28136
28421
|
}
|
|
28137
28422
|
function getPropertyValue(target, property, context) {
|
|
28138
28423
|
if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
|
|
28424
|
+
if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
|
|
28425
|
+
const prototype = getBoxedPrototype(target, context.budget);
|
|
28426
|
+
if (prototype !== void 0) {
|
|
28427
|
+
if (typeof target === "string" && (property === "length" || getStringIndex(property) !== void 0))
|
|
28428
|
+
return getStringMember(target, property, context.budget);
|
|
28429
|
+
return getMemberValue(prototype, property, context);
|
|
28430
|
+
}
|
|
28431
|
+
}
|
|
28139
28432
|
if (typeof target === "string") return getStringMember(target, property, context.budget);
|
|
28140
28433
|
if (typeof target === "number") return getNumberMember(property, context.budget);
|
|
28141
28434
|
if (typeof target === "boolean") return void 0;
|
|
@@ -28307,6 +28600,15 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
28307
28600
|
...reference,
|
|
28308
28601
|
property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
|
|
28309
28602
|
};
|
|
28603
|
+
if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") && getBoxedPrototype(member.object, context.budget) !== void 0) {
|
|
28604
|
+
if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
|
|
28605
|
+
if (typeof member.object === "string" && isStringMethodName(member.property))
|
|
28606
|
+
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
28607
|
+
if (typeof member.object === "number" && isNumberMethodName(member.property))
|
|
28608
|
+
return evaluateNumberMethodCall(node, member.object, member.property, context);
|
|
28609
|
+
}
|
|
28610
|
+
return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
|
|
28611
|
+
}
|
|
28310
28612
|
if (typeof member.object === "string" && isStringMethodName(member.property)) {
|
|
28311
28613
|
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
28312
28614
|
}
|
|
@@ -28656,7 +28958,7 @@ function hasSandboxProperty(value, key, context) {
|
|
|
28656
28958
|
while (typeof current === "object" && current !== null) {
|
|
28657
28959
|
if (isGuestHostObject(current)) return hasHostObjectMember(current, key);
|
|
28658
28960
|
if (hasOwnSandboxProperty(current, key, false)) return true;
|
|
28659
|
-
if (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current)) {
|
|
28961
|
+
if (!(isGuestClosure(current) && hasExplicitSandboxPrototype(current)) && (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current))) {
|
|
28660
28962
|
return getPropertyValue(current, key, context) !== void 0;
|
|
28661
28963
|
}
|
|
28662
28964
|
current = getSandboxPrototype(current, context.budget);
|
|
@@ -28668,33 +28970,41 @@ function hasSandboxProperty(value, key, context) {
|
|
|
28668
28970
|
return false;
|
|
28669
28971
|
}
|
|
28670
28972
|
async function applyCompoundAssignmentOperator(operator, left, right, context) {
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
|
|
28696
|
-
|
|
28697
|
-
|
|
28973
|
+
const convertingObject = typeof left === "object" && left !== null;
|
|
28974
|
+
let convertedLeft;
|
|
28975
|
+
const release = retainValues(context.budget, () => [convertedLeft]);
|
|
28976
|
+
try {
|
|
28977
|
+
left = await toNumericPrimitive(left, context);
|
|
28978
|
+
if (convertingObject) convertedLeft = left;
|
|
28979
|
+
right = await toNumericPrimitive(right, context);
|
|
28980
|
+
switch (operator) {
|
|
28981
|
+
case "+=":
|
|
28982
|
+
return applyAdditionOperator(left, right, context);
|
|
28983
|
+
case "-=":
|
|
28984
|
+
return toNumber(left) - toNumber(right);
|
|
28985
|
+
case "*=":
|
|
28986
|
+
return toNumber(left) * toNumber(right);
|
|
28987
|
+
case "/=":
|
|
28988
|
+
return toNumber(left) / toNumber(right);
|
|
28989
|
+
case "%=":
|
|
28990
|
+
return toNumber(left) % toNumber(right);
|
|
28991
|
+
case "**=":
|
|
28992
|
+
return toNumber(left) ** toNumber(right);
|
|
28993
|
+
case "&=":
|
|
28994
|
+
return toNumber(left) & toNumber(right);
|
|
28995
|
+
case "|=":
|
|
28996
|
+
return toNumber(left) | toNumber(right);
|
|
28997
|
+
case "^=":
|
|
28998
|
+
return toNumber(left) ^ toNumber(right);
|
|
28999
|
+
case "<<=":
|
|
29000
|
+
return toNumber(left) << toNumber(right);
|
|
29001
|
+
case ">>=":
|
|
29002
|
+
return toNumber(left) >> toNumber(right);
|
|
29003
|
+
case ">>>=":
|
|
29004
|
+
return toNumber(left) >>> toNumber(right);
|
|
29005
|
+
}
|
|
29006
|
+
} finally {
|
|
29007
|
+
release();
|
|
28698
29008
|
}
|
|
28699
29009
|
}
|
|
28700
29010
|
function applyAdditionOperator(left, right, context) {
|
|
@@ -29091,12 +29401,12 @@ async function evaluateSpreadElement(node, context) {
|
|
|
29091
29401
|
result: value
|
|
29092
29402
|
};
|
|
29093
29403
|
}
|
|
29094
|
-
const iterator = getSandboxIterator(value.value, context.budget);
|
|
29404
|
+
const iterator = getSandboxIterator(value.value, context.budget, createCoercionContext(context));
|
|
29095
29405
|
if (iterator === void 0) {
|
|
29096
29406
|
throw new TypeError("Spread arguments must evaluate to an iterable.");
|
|
29097
29407
|
}
|
|
29098
29408
|
const spreadValues = [];
|
|
29099
|
-
const release = retainValues(context.budget, () => [value.value, ...spreadValues]);
|
|
29409
|
+
const release = retainValues(context.budget, () => [value.value, iterator.retainedValue, ...spreadValues]);
|
|
29100
29410
|
try {
|
|
29101
29411
|
while (true) {
|
|
29102
29412
|
const next = await iterator.next();
|
|
@@ -30176,6 +30486,30 @@ function copyHostValueToSandbox(value, stackFrames, options, state, path) {
|
|
|
30176
30486
|
state
|
|
30177
30487
|
);
|
|
30178
30488
|
}
|
|
30489
|
+
const primitive = nativeBoxedValue(value);
|
|
30490
|
+
if (primitive !== void 0) {
|
|
30491
|
+
if (typeof primitive === "string") budget.allocateString(primitive);
|
|
30492
|
+
const original = value;
|
|
30493
|
+
const existing = state.seen.get(original);
|
|
30494
|
+
if (existing !== void 0) return existing;
|
|
30495
|
+
const copy = createSandboxBox(primitive);
|
|
30496
|
+
state.seen.set(original, copy);
|
|
30497
|
+
budget.chargeDataUsage(measureSandboxData([copy]));
|
|
30498
|
+
for (const [key, descriptor] of boxedDataProperties(original)) {
|
|
30499
|
+
if (!("value" in descriptor)) throw new TypeError(`Unsupported sandbox value at ${joinPath2(path, key)}: accessor property`);
|
|
30500
|
+
Object.defineProperty(copy, budget.allocateString(key), {
|
|
30501
|
+
...descriptor,
|
|
30502
|
+
value: copyHostValueToSandbox(
|
|
30503
|
+
descriptor.value,
|
|
30504
|
+
stackFrames,
|
|
30505
|
+
{ ...options, capabilityPath: [...options.capabilityPath ?? [], key] },
|
|
30506
|
+
state,
|
|
30507
|
+
joinPath2(path, key)
|
|
30508
|
+
)
|
|
30509
|
+
});
|
|
30510
|
+
}
|
|
30511
|
+
return copy;
|
|
30512
|
+
}
|
|
30179
30513
|
const date = copyNativeDate(value);
|
|
30180
30514
|
if (date !== void 0) {
|
|
30181
30515
|
const existing = state.seen.get(value);
|
|
@@ -30585,7 +30919,7 @@ function createReplayableRandom(options = {}) {
|
|
|
30585
30919
|
|
|
30586
30920
|
// packages/safe-js/src/realm.ts
|
|
30587
30921
|
import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
|
|
30588
|
-
import { types as
|
|
30922
|
+
import { types as types6 } from "node:util";
|
|
30589
30923
|
|
|
30590
30924
|
// packages/safe-js/src/interp/globals/console-json.ts
|
|
30591
30925
|
function createConsoleJsonGlobals(options) {
|
|
@@ -30594,12 +30928,18 @@ function createConsoleJsonGlobals(options) {
|
|
|
30594
30928
|
JSON: {
|
|
30595
30929
|
parse: createSandboxClosure({
|
|
30596
30930
|
sandbox: true,
|
|
30597
|
-
call: async ([text]) =>
|
|
30931
|
+
call: async ([text], context) => {
|
|
30932
|
+
const converted = sandboxString(text, options.budget, context);
|
|
30933
|
+
return copyJsonToSandbox(
|
|
30934
|
+
JSON.parse(converted instanceof Promise ? await converted : converted),
|
|
30935
|
+
options.budget
|
|
30936
|
+
);
|
|
30937
|
+
},
|
|
30598
30938
|
name: "parse"
|
|
30599
30939
|
}),
|
|
30600
30940
|
stringify: createSandboxClosure({
|
|
30601
30941
|
sandbox: true,
|
|
30602
|
-
call: async ([value, replacer, indent]) => stringifyJson(value, replacer, indent, options.budget),
|
|
30942
|
+
call: async ([value, replacer, indent], context) => stringifyJson(value, replacer, indent, options.budget, context),
|
|
30603
30943
|
name: "stringify"
|
|
30604
30944
|
})
|
|
30605
30945
|
},
|
|
@@ -30660,11 +31000,7 @@ function createConsoleJsonGlobals(options) {
|
|
|
30660
31000
|
)
|
|
30661
31001
|
};
|
|
30662
31002
|
}
|
|
30663
|
-
function
|
|
30664
|
-
const text = budget.allocateString(toJsonParseText(input));
|
|
30665
|
-
return copyJsonToSandbox(JSON.parse(text), budget);
|
|
30666
|
-
}
|
|
30667
|
-
async function stringifyJson(value, replacer, indent, budget) {
|
|
31003
|
+
async function stringifyJson(value, replacer, indent, budget, context) {
|
|
30668
31004
|
if (replacer !== void 0 && replacer !== null && !isSandboxClosure(replacer)) {
|
|
30669
31005
|
throw new TypeError(
|
|
30670
31006
|
"JSON.stringify(value, replacer, indent) only supports function, null, or undefined replacers."
|
|
@@ -30679,6 +31015,7 @@ async function stringifyJson(value, replacer, indent, budget) {
|
|
|
30679
31015
|
defineDataProperty(holder, "", value);
|
|
30680
31016
|
const output = await stringifyProperty("", holder, {
|
|
30681
31017
|
budget,
|
|
31018
|
+
context,
|
|
30682
31019
|
gap: normalizeStringifyGap(indent),
|
|
30683
31020
|
replacer: isSandboxClosure(replacer) ? replacer : void 0,
|
|
30684
31021
|
stack: []
|
|
@@ -30688,15 +31025,6 @@ async function stringifyJson(value, replacer, indent, budget) {
|
|
|
30688
31025
|
}
|
|
30689
31026
|
return budget.allocateString(output);
|
|
30690
31027
|
}
|
|
30691
|
-
function toJsonParseText(input) {
|
|
30692
|
-
if (Array.isArray(input)) {
|
|
30693
|
-
return input.map((entry) => entry === null || entry === void 0 ? "" : toJsonParseText(entry)).join(",");
|
|
30694
|
-
}
|
|
30695
|
-
if (typeof input === "object" && input !== null) {
|
|
30696
|
-
return "[object Object]";
|
|
30697
|
-
}
|
|
30698
|
-
return String(input);
|
|
30699
|
-
}
|
|
30700
31028
|
async function stringifyProperty(key, holder, state, indent = "") {
|
|
30701
31029
|
let value = getOwnDataValue(holder, key);
|
|
30702
31030
|
if (isSandboxDate(value)) {
|
|
@@ -30713,6 +31041,10 @@ async function stringifyProperty(key, holder, state, indent = "") {
|
|
|
30713
31041
|
return stringifyValue(value, state, indent);
|
|
30714
31042
|
}
|
|
30715
31043
|
async function stringifyValue(value, state, indent) {
|
|
31044
|
+
if (isSandboxBox(value)) {
|
|
31045
|
+
const primitive = boxedValue(value);
|
|
31046
|
+
value = typeof primitive === "number" ? await sandboxNumber(value, state.budget, state.context) : typeof primitive === "string" ? await sandboxString(value, state.budget, state.context) : primitive;
|
|
31047
|
+
}
|
|
30716
31048
|
if (value === null) {
|
|
30717
31049
|
return "null";
|
|
30718
31050
|
}
|
|
@@ -30997,7 +31329,7 @@ function structuredCloneSandboxValue(value, budget, parent) {
|
|
|
30997
31329
|
const operation = budget.acquireCompileOwner(false, parent?.owner);
|
|
30998
31330
|
const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
|
|
30999
31331
|
try {
|
|
31000
|
-
const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
|
|
31332
|
+
const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true, structuredClone: true });
|
|
31001
31333
|
assertSandboxGraphDepth(clone);
|
|
31002
31334
|
assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
|
|
31003
31335
|
allocateProducedSandboxValue(clone, budget);
|
|
@@ -31034,6 +31366,72 @@ function assertStructuredCloneable(value, seen) {
|
|
|
31034
31366
|
}
|
|
31035
31367
|
}
|
|
31036
31368
|
|
|
31369
|
+
// packages/safe-js/src/interp/globals/primitives.ts
|
|
31370
|
+
function createPrimitiveConstructor(options, budget) {
|
|
31371
|
+
const initial = { Number: 0, String: "", Boolean: false }[options.name];
|
|
31372
|
+
const kind = typeof initial;
|
|
31373
|
+
const prototype = createSandboxBox(initial);
|
|
31374
|
+
const allocate = (value) => {
|
|
31375
|
+
const box = createSandboxBox(value);
|
|
31376
|
+
budget.chargeDataUsage(measureSandboxData([box]));
|
|
31377
|
+
return box;
|
|
31378
|
+
};
|
|
31379
|
+
const constructor = createSandboxClosure({
|
|
31380
|
+
guest: true,
|
|
31381
|
+
sandbox: true,
|
|
31382
|
+
name: options.name,
|
|
31383
|
+
length: 1,
|
|
31384
|
+
call: options.call,
|
|
31385
|
+
construct: (args, context) => {
|
|
31386
|
+
const value = options.call(args, context);
|
|
31387
|
+
return value instanceof Promise ? value.then(allocate) : allocate(value);
|
|
31388
|
+
}
|
|
31389
|
+
});
|
|
31390
|
+
const properties = materializeFunctionProperties(constructor);
|
|
31391
|
+
Object.defineProperty(properties, "prototype", { value: prototype, writable: false });
|
|
31392
|
+
Object.defineProperty(prototype, "constructor", {
|
|
31393
|
+
value: constructor,
|
|
31394
|
+
writable: true,
|
|
31395
|
+
configurable: true
|
|
31396
|
+
});
|
|
31397
|
+
for (const [name, value] of Object.entries(options.properties ?? {}))
|
|
31398
|
+
Object.defineProperty(properties, name, {
|
|
31399
|
+
value,
|
|
31400
|
+
writable: isSandboxClosure(value),
|
|
31401
|
+
configurable: isSandboxClosure(value)
|
|
31402
|
+
});
|
|
31403
|
+
const methods = /* @__PURE__ */ new Map([
|
|
31404
|
+
[
|
|
31405
|
+
"valueOf",
|
|
31406
|
+
createSandboxClosure({
|
|
31407
|
+
sandbox: true,
|
|
31408
|
+
name: "valueOf",
|
|
31409
|
+
length: 0,
|
|
31410
|
+
call: (_args, context) => primitiveReceiver(context?.thisValue, kind)
|
|
31411
|
+
})
|
|
31412
|
+
]
|
|
31413
|
+
]);
|
|
31414
|
+
if (kind === "number") {
|
|
31415
|
+
for (const name of numberMethodNames) methods.set(name, getNumberMember(name, budget));
|
|
31416
|
+
} else {
|
|
31417
|
+
methods.set(
|
|
31418
|
+
"toString",
|
|
31419
|
+
createSandboxClosure({
|
|
31420
|
+
sandbox: true,
|
|
31421
|
+
name: "toString",
|
|
31422
|
+
length: 0,
|
|
31423
|
+
call: (_args, context) => budget.allocateString(String(primitiveReceiver(context?.thisValue, kind)))
|
|
31424
|
+
})
|
|
31425
|
+
);
|
|
31426
|
+
if (kind === "string")
|
|
31427
|
+
for (const name of stringMethodNames) methods.set(name, getStringMember("", name, budget));
|
|
31428
|
+
}
|
|
31429
|
+
for (const [name, value] of methods)
|
|
31430
|
+
Object.defineProperty(prototype, name, { value, writable: true, configurable: true });
|
|
31431
|
+
installBoxedPrototype(budget, prototype, constructor);
|
|
31432
|
+
return constructor;
|
|
31433
|
+
}
|
|
31434
|
+
|
|
31037
31435
|
// packages/safe-js/src/interp/globals/object-array.ts
|
|
31038
31436
|
function createObjectArrayGlobals(options) {
|
|
31039
31437
|
return {
|
|
@@ -31099,6 +31497,7 @@ function createObjectArrayGlobals(options) {
|
|
|
31099
31497
|
sandbox: true,
|
|
31100
31498
|
call: ([value]) => {
|
|
31101
31499
|
if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
|
|
31500
|
+
if (value !== null && value !== void 0 && typeof value !== "object") value = createSandboxBox(value);
|
|
31102
31501
|
objectProperties(value);
|
|
31103
31502
|
return getSandboxPrototype(value, options.budget);
|
|
31104
31503
|
},
|
|
@@ -31138,11 +31537,11 @@ function createObjectArrayGlobals(options) {
|
|
|
31138
31537
|
fromEntries: createSandboxClosure({
|
|
31139
31538
|
sandbox: true,
|
|
31140
31539
|
call: ([value], context) => {
|
|
31141
|
-
const iterator = getSandboxIterator(value, options.budget);
|
|
31540
|
+
const iterator = getSandboxIterator(value, options.budget, context);
|
|
31142
31541
|
if (iterator === void 0) {
|
|
31143
31542
|
throw new TypeError("Object.fromEntries requires an iterable.");
|
|
31144
31543
|
}
|
|
31145
|
-
if (context === void 0 && !iterator.generator) {
|
|
31544
|
+
if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
|
|
31146
31545
|
return allocateProducedSandboxValue(
|
|
31147
31546
|
Object.setPrototypeOf(
|
|
31148
31547
|
Reflect.apply(Object.fromEntries, Object, [{ [Symbol.iterator]: () => iterator }]),
|
|
@@ -31200,8 +31599,7 @@ function createObjectArrayGlobals(options) {
|
|
|
31200
31599
|
})
|
|
31201
31600
|
}
|
|
31202
31601
|
}),
|
|
31203
|
-
String:
|
|
31204
|
-
sandbox: true,
|
|
31602
|
+
String: createPrimitiveConstructor({
|
|
31205
31603
|
call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
|
|
31206
31604
|
name: "String",
|
|
31207
31605
|
properties: {
|
|
@@ -31221,9 +31619,8 @@ function createObjectArrayGlobals(options) {
|
|
|
31221
31619
|
name: "fromCodePoint"
|
|
31222
31620
|
})
|
|
31223
31621
|
}
|
|
31224
|
-
}),
|
|
31225
|
-
Number:
|
|
31226
|
-
sandbox: true,
|
|
31622
|
+
}, options.budget),
|
|
31623
|
+
Number: createPrimitiveConstructor({
|
|
31227
31624
|
call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
|
|
31228
31625
|
name: "Number",
|
|
31229
31626
|
properties: {
|
|
@@ -31257,12 +31654,11 @@ function createObjectArrayGlobals(options) {
|
|
|
31257
31654
|
NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
|
|
31258
31655
|
POSITIVE_INFINITY: Number.POSITIVE_INFINITY
|
|
31259
31656
|
}
|
|
31260
|
-
}),
|
|
31261
|
-
Boolean:
|
|
31262
|
-
sandbox: true,
|
|
31657
|
+
}, options.budget),
|
|
31658
|
+
Boolean: createPrimitiveConstructor({
|
|
31263
31659
|
call: ([value]) => Boolean(value),
|
|
31264
31660
|
name: "Boolean"
|
|
31265
|
-
})
|
|
31661
|
+
}, options.budget)
|
|
31266
31662
|
};
|
|
31267
31663
|
}
|
|
31268
31664
|
async function objectFromSandboxEntries(items, iterator, budget, context) {
|
|
@@ -31272,7 +31668,7 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
|
|
|
31272
31668
|
let value;
|
|
31273
31669
|
let failure;
|
|
31274
31670
|
const retained = {};
|
|
31275
|
-
budget.setRetainedValues(retained, () => [items, object, entry, key, value, failure]);
|
|
31671
|
+
budget.setRetainedValues(retained, () => [items, iterator.retainedValue, object, entry, key, value, failure]);
|
|
31276
31672
|
const checkData = createDataCheckpoint(budget, context);
|
|
31277
31673
|
const closeOnThrow = async (error) => {
|
|
31278
31674
|
failure = isCapturedException(error) ? error.reason : error;
|
|
@@ -31323,6 +31719,10 @@ function assignSandboxValues(target, sources, budget) {
|
|
|
31323
31719
|
if (target === null || target === void 0) {
|
|
31324
31720
|
throw new TypeError("Object.assign(target, ...sources) requires a non-null target.");
|
|
31325
31721
|
}
|
|
31722
|
+
if (typeof target !== "object") {
|
|
31723
|
+
target = createSandboxBox(target);
|
|
31724
|
+
budget.chargeDataUsage(measureSandboxData([target]));
|
|
31725
|
+
}
|
|
31326
31726
|
if (!isGuestClosure(target) && !isAssignableSandboxTarget(target)) {
|
|
31327
31727
|
throw new TypeError("Object.assign(target, ...sources) requires an object or array target.");
|
|
31328
31728
|
}
|
|
@@ -31392,13 +31792,13 @@ async function arrayFromSandboxValues(args, budget, context) {
|
|
|
31392
31792
|
throw new TypeError("Array.from requires a non-null input.");
|
|
31393
31793
|
}
|
|
31394
31794
|
const read = (property) => context?.getProperty !== void 0 ? context.getProperty(items, property) : getSandboxDataProperty(items, property, budget);
|
|
31395
|
-
const iterator = getSandboxIterator(items, budget);
|
|
31795
|
+
const iterator = getSandboxIterator(items, budget, context);
|
|
31396
31796
|
const constructor = context?.thisValue;
|
|
31397
31797
|
let result;
|
|
31398
31798
|
let currentValue;
|
|
31399
31799
|
let failure;
|
|
31400
31800
|
const retained = {};
|
|
31401
|
-
budget.setRetainedValues(retained, () => [items, mapFn, constructor, result, currentValue, failure]);
|
|
31801
|
+
budget.setRetainedValues(retained, () => [items, iterator?.retainedValue, mapFn, constructor, result, currentValue, failure]);
|
|
31402
31802
|
const checkData = createDataCheckpoint(budget, context);
|
|
31403
31803
|
const closeOnThrow = async (error) => {
|
|
31404
31804
|
failure = isCapturedException(error) ? error.reason : error;
|
|
@@ -31657,7 +32057,7 @@ var RealmState = class {
|
|
|
31657
32057
|
throw new TypeError("Realm limits must be positive safe integers with supported names.");
|
|
31658
32058
|
this.limits[name] = Number(value);
|
|
31659
32059
|
}
|
|
31660
|
-
if (options.extensions !== void 0 && (!Array.isArray(options.extensions) ||
|
|
32060
|
+
if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types6.isProxy(options.extensions)))
|
|
31661
32061
|
throw new TypeError("Extensions must be a registration array.");
|
|
31662
32062
|
const registrations = options.extensions ?? [];
|
|
31663
32063
|
const extensions = [];
|
|
@@ -31892,7 +32292,7 @@ var RealmState = class {
|
|
|
31892
32292
|
return this.phase.run(phase, () => {
|
|
31893
32293
|
try {
|
|
31894
32294
|
const result = call();
|
|
31895
|
-
if (
|
|
32295
|
+
if (types6.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
|
|
31896
32296
|
return Promise.resolve(result).then(
|
|
31897
32297
|
async (value) => {
|
|
31898
32298
|
await Promise.allSettled(phase.pending);
|
|
@@ -31961,7 +32361,7 @@ var RealmState = class {
|
|
|
31961
32361
|
},
|
|
31962
32362
|
read: (operation, validate) => {
|
|
31963
32363
|
const value = this.invokeHost(operation, operation);
|
|
31964
|
-
if (
|
|
32364
|
+
if (types6.isPromise(value)) {
|
|
31965
32365
|
void Promise.resolve(value).catch(() => void 0);
|
|
31966
32366
|
throw new TypeError("Live property operations must be synchronous.");
|
|
31967
32367
|
}
|
|
@@ -31969,7 +32369,7 @@ var RealmState = class {
|
|
|
31969
32369
|
},
|
|
31970
32370
|
write: (operation, value) => {
|
|
31971
32371
|
const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
|
|
31972
|
-
if (
|
|
32372
|
+
if (types6.isPromise(result)) {
|
|
31973
32373
|
void Promise.resolve(result).catch(() => void 0);
|
|
31974
32374
|
throw new TypeError("Live property setters must be synchronous.");
|
|
31975
32375
|
}
|
|
@@ -32178,7 +32578,7 @@ var RealmState = class {
|
|
|
32178
32578
|
}
|
|
32179
32579
|
});
|
|
32180
32580
|
const output = getExtensionSetup(extension)(context);
|
|
32181
|
-
if (
|
|
32581
|
+
if (types6.isPromise(output)) {
|
|
32182
32582
|
void Promise.resolve(output).catch(() => void 0);
|
|
32183
32583
|
throw new TypeError("Extension setup must be synchronous.");
|
|
32184
32584
|
}
|
|
@@ -32370,7 +32770,7 @@ var RealmState = class {
|
|
|
32370
32770
|
};
|
|
32371
32771
|
function readModules(input) {
|
|
32372
32772
|
const entries = (value, label) => {
|
|
32373
|
-
if (
|
|
32773
|
+
if (types6.isMap(value) && !types6.isProxy(value)) {
|
|
32374
32774
|
const result = [...Map.prototype.entries.call(value)];
|
|
32375
32775
|
if (result.length > 4096 || result.some(([key]) => typeof key !== "string" || key.length === 0))
|
|
32376
32776
|
throw new TypeError(`${label} requires bounded string keys.`);
|
|
@@ -33615,4 +34015,4 @@ export {
|
|
|
33615
34015
|
FileSnapshotBackend,
|
|
33616
34016
|
run
|
|
33617
34017
|
};
|
|
33618
|
-
//# sourceMappingURL=chunk-
|
|
34018
|
+
//# sourceMappingURL=chunk-XO7B4P27.js.map
|