poe-code 14.0.79 → 14.0.80
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 +252 -100
- 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-B3AL4KJ3.js → chunk-34G5WW2O.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-BGSPSHLP.js → chunk-M4L3EZHL.js} +220 -93
- package/packages/safe-js/dist/chunks/chunk-M4L3EZHL.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 +2 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/interp/generator-properties.d.ts +3 -0
- package/packages/safe-js/dist/interp/generator-properties.js +9 -0
- package/packages/safe-js/dist/interp/globals/function.d.ts +2 -0
- package/packages/safe-js/dist/interp/globals/function.js +24 -0
- package/packages/safe-js/dist/interp/globals/object-array.js +9 -6
- package/packages/safe-js/dist/interp/globals/object.js +2 -1
- package/packages/safe-js/dist/interp/globals.js +2 -0
- package/packages/safe-js/dist/interp/interpreter.js +13 -7
- package/packages/safe-js/dist/interp/iteration.js +37 -4
- package/packages/safe-js/dist/interp/methods/function.d.ts +4 -1
- package/packages/safe-js/dist/interp/methods/function.js +2 -2
- package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
- package/packages/safe-js/dist/interp/object-model.js +67 -17
- package/packages/safe-js/dist/interp/string-coercion.js +3 -2
- package/packages/safe-js/dist/interp/values.js +21 -3
- package/packages/safe-js/dist/snapshot/guest-heap-validation.js +3 -1
- package/packages/safe-js/dist/snapshot/guest-heap.d.ts +1 -0
- package/packages/safe-js/dist/snapshot/guest-heap.js +4 -0
- package/packages/safe-js/dist/snapshot/restore.js +8 -0
- package/packages/safe-js/dist/chunks/chunk-BGSPSHLP.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-B3AL4KJ3.js.map → chunk-34G5WW2O.js.map} +0 -0
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveFsConfig,
|
|
23
23
|
splitFrontmatter,
|
|
24
24
|
withBrokenPipeGuard
|
|
25
|
-
} from "./chunks/chunk-
|
|
25
|
+
} from "./chunks/chunk-34G5WW2O.js";
|
|
26
26
|
import {
|
|
27
27
|
Budget,
|
|
28
28
|
SandboxError,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
replaceErrorStack,
|
|
35
35
|
restore,
|
|
36
36
|
run
|
|
37
|
-
} from "./chunks/chunk-
|
|
37
|
+
} from "./chunks/chunk-M4L3EZHL.js";
|
|
38
38
|
import "./chunks/chunk-M2DLCGEF.js";
|
|
39
39
|
import "./chunks/chunk-Q7USUEL7.js";
|
|
40
40
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -7,6 +7,7 @@ import { regexpIteratorState, isSandboxRegExpIterator } from "./interp/regexp-it
|
|
|
7
7
|
import { isSandboxMap, isSandboxSet } from "./interp/collection-brands.js";
|
|
8
8
|
import { boxedDataProperties, isSandboxBox } from "./interp/boxed.js";
|
|
9
9
|
import { regexGuestProperties } from "./interp/regexp-properties.js";
|
|
10
|
+
import { generatorGuestProperties } from "./interp/generator-properties.js";
|
|
10
11
|
export const MAX_DATA_DEPTH = 1_024;
|
|
11
12
|
export class SnapshotBudgetError extends Error {
|
|
12
13
|
code = "budgetExceeded";
|
|
@@ -67,7 +68,7 @@ function walkGraphDepth(root, rootPath, assertDepth) {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
function graphEntries(value) {
|
|
70
|
-
const properties = regexGuestProperties.get(value);
|
|
71
|
+
const properties = regexGuestProperties.get(value) ?? generatorGuestProperties.get(value);
|
|
71
72
|
if (properties !== undefined)
|
|
72
73
|
return Reflect.ownKeys(properties).flatMap(key => {
|
|
73
74
|
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
runWithSpawnUsageAccumulator,
|
|
27
27
|
splitFrontmatter,
|
|
28
28
|
supportsSpawnMode
|
|
29
|
-
} from "./chunks/chunk-
|
|
29
|
+
} from "./chunks/chunk-34G5WW2O.js";
|
|
30
30
|
import {
|
|
31
31
|
Budget,
|
|
32
32
|
FileSnapshotBackend,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
registerPendingHostCallPolicy,
|
|
51
51
|
restore,
|
|
52
52
|
run
|
|
53
|
-
} from "./chunks/chunk-
|
|
53
|
+
} from "./chunks/chunk-M4L3EZHL.js";
|
|
54
54
|
import "./chunks/chunk-M2DLCGEF.js";
|
|
55
55
|
import "./chunks/chunk-Q7USUEL7.js";
|
|
56
56
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const generatorGuestProperties = new WeakMap();
|
|
2
|
+
export function getGeneratorProperties(value) {
|
|
3
|
+
let properties = generatorGuestProperties.get(value);
|
|
4
|
+
if (properties === undefined) {
|
|
5
|
+
properties = Object.create(null);
|
|
6
|
+
generatorGuestProperties.set(value, properties);
|
|
7
|
+
}
|
|
8
|
+
return properties;
|
|
9
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { invokeBuiltinClosure } from "../builtin-call.js";
|
|
2
|
+
import { callFunctionMethod } from "../methods/function.js";
|
|
3
|
+
import { getSandboxPrototype, installFunctionPrototype, materializeFunctionProperties, setSandboxPrototype } from "../object-model.js";
|
|
4
|
+
import { createSandboxClosure } from "../values.js";
|
|
5
|
+
export function createFunctionPrototype(budget) {
|
|
6
|
+
const prototype = createSandboxClosure({ guest: true, sandbox: true, name: "", length: 0, call: () => undefined });
|
|
7
|
+
const properties = materializeFunctionProperties(prototype);
|
|
8
|
+
// Invocation support does not grant the host's dynamic source constructor.
|
|
9
|
+
Object.defineProperty(properties, "constructor", { value: undefined, writable: true, configurable: true });
|
|
10
|
+
for (const [name, length] of [["call", 1], ["apply", 2], ["bind", 1], ["toString", 0]]) {
|
|
11
|
+
Object.defineProperty(properties, name, { writable: true, configurable: true,
|
|
12
|
+
value: createSandboxClosure({ guest: true, sandbox: true, name, length,
|
|
13
|
+
call: (args, context) => callFunctionMethod(context?.thisValue, name, args, {
|
|
14
|
+
budget,
|
|
15
|
+
callClosure: (target, values, stack, thisValue, construct, newTarget) => context?.invokeClosure !== undefined
|
|
16
|
+
? context.invokeClosure(target, values, thisValue, construct, newTarget)
|
|
17
|
+
: invokeBuiltinClosure(target, values, budget, { ...context, stack, thisValue, newTarget }, thisValue, construct)
|
|
18
|
+
}, context?.stack ?? [], context)
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
setSandboxPrototype(prototype, getSandboxPrototype(Object.create(null), budget));
|
|
23
|
+
installFunctionPrototype(budget, prototype);
|
|
24
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isFatalSandboxError } from "../budget.js";
|
|
2
|
+
import { getGeneratorProperties } from "../generator-properties.js";
|
|
2
3
|
import { accessorAdapter, accessorClosure, readPropertyDescriptor, retainedAccessorClosures } from "../accessors.js";
|
|
3
4
|
import { invokeBuiltinClosure } from "../builtin-call.js";
|
|
4
5
|
import { createDataCheckpoint } from "../data-checkpoint.js";
|
|
@@ -180,14 +181,14 @@ export function createObjectArrayGlobals(options) {
|
|
|
180
181
|
call: ([value]) => {
|
|
181
182
|
if (isGuestHostObject(value))
|
|
182
183
|
throw new TypeError("Live host objects cannot be made non-extensible.");
|
|
183
|
-
Object.preventExtensions(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
184
|
+
Object.preventExtensions(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
184
185
|
return value;
|
|
185
186
|
},
|
|
186
187
|
name: "preventExtensions"
|
|
187
188
|
}),
|
|
188
189
|
isExtensible: createSandboxClosure({
|
|
189
190
|
sandbox: true,
|
|
190
|
-
call: ([value]) => Object.isExtensible(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
191
|
+
call: ([value]) => Object.isExtensible(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
191
192
|
name: "isExtensible"
|
|
192
193
|
}),
|
|
193
194
|
seal: createSandboxClosure({
|
|
@@ -195,14 +196,14 @@ export function createObjectArrayGlobals(options) {
|
|
|
195
196
|
call: ([value]) => {
|
|
196
197
|
if (isGuestHostObject(value))
|
|
197
198
|
throw new TypeError("Live host objects cannot be sealed.");
|
|
198
|
-
Object.seal(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
199
|
+
Object.seal(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
199
200
|
return value;
|
|
200
201
|
},
|
|
201
202
|
name: "seal"
|
|
202
203
|
}),
|
|
203
204
|
isSealed: createSandboxClosure({
|
|
204
205
|
sandbox: true,
|
|
205
|
-
call: ([value]) => Object.isSealed(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
206
|
+
call: ([value]) => Object.isSealed(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
206
207
|
name: "isSealed"
|
|
207
208
|
}),
|
|
208
209
|
freeze: createSandboxClosure({
|
|
@@ -211,7 +212,7 @@ export function createObjectArrayGlobals(options) {
|
|
|
211
212
|
if (isGuestHostObject(value))
|
|
212
213
|
throw new TypeError("Live host objects cannot be frozen.");
|
|
213
214
|
if (typeof value === "object" && value !== null) {
|
|
214
|
-
Object.freeze(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
215
|
+
Object.freeze(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
215
216
|
}
|
|
216
217
|
return value;
|
|
217
218
|
},
|
|
@@ -219,7 +220,7 @@ export function createObjectArrayGlobals(options) {
|
|
|
219
220
|
}),
|
|
220
221
|
isFrozen: createSandboxClosure({
|
|
221
222
|
sandbox: true,
|
|
222
|
-
call: ([value]) => Object.isFrozen(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
223
|
+
call: ([value]) => Object.isFrozen(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
223
224
|
name: "isFrozen"
|
|
224
225
|
}),
|
|
225
226
|
assign: createSandboxClosure({
|
|
@@ -556,6 +557,8 @@ function reflectionProperties(value) {
|
|
|
556
557
|
return objectProperties(value);
|
|
557
558
|
}
|
|
558
559
|
export function objectProperties(value, mutable = false) {
|
|
560
|
+
if (isSandboxGenerator(value))
|
|
561
|
+
return getGeneratorProperties(value);
|
|
559
562
|
if (isSandboxPromise(value))
|
|
560
563
|
return getPromiseProperties(value);
|
|
561
564
|
if (isSandboxMap(value) || isSandboxSet(value))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertSandboxDataDepth } from "../../graph-depth.js";
|
|
2
|
+
import { getGeneratorProperties } from "../generator-properties.js";
|
|
2
3
|
import { readPropertyDescriptor } from "../accessors.js";
|
|
3
4
|
import { isSandboxArguments } from "../arguments.js";
|
|
4
5
|
import { isSandboxDate } from "../date.js";
|
|
@@ -153,7 +154,7 @@ export function hasOwnSandboxProperty(value, key, enumerable) {
|
|
|
153
154
|
else if (isSandboxPromise(value))
|
|
154
155
|
properties = getPromiseProperties(value);
|
|
155
156
|
else if (isSandboxGenerator(value))
|
|
156
|
-
|
|
157
|
+
properties = getGeneratorProperties(value);
|
|
157
158
|
else if (isSandboxRegex(value))
|
|
158
159
|
properties = getRegexProperties(value);
|
|
159
160
|
else
|
|
@@ -7,6 +7,7 @@ import { createRegexGlobals } from "./globals/regex.js";
|
|
|
7
7
|
import { createMiscGlobals } from "./globals/misc.js";
|
|
8
8
|
import { createUriGlobals } from "./globals/uri.js";
|
|
9
9
|
import { createObjectArrayGlobals } from "./globals/object-array.js";
|
|
10
|
+
import { createFunctionPrototype } from "./globals/function.js";
|
|
10
11
|
import { createPromiseGlobals } from "./promise.js";
|
|
11
12
|
import { createDateGlobal } from "./globals/date.js";
|
|
12
13
|
import { createSymbolGlobal } from "./globals/symbol.js";
|
|
@@ -28,6 +29,7 @@ export function createBuiltinBindings(options) {
|
|
|
28
29
|
...createPromiseGlobals(options),
|
|
29
30
|
...createRegexGlobals(options)
|
|
30
31
|
};
|
|
32
|
+
createFunctionPrototype(options.budget);
|
|
31
33
|
registerBuiltinIdentities(options.budget, bindings);
|
|
32
34
|
return bindings;
|
|
33
35
|
}
|
|
@@ -29,6 +29,7 @@ import { getPromiseMember } from "./promise.js";
|
|
|
29
29
|
import { acquireSandboxIterator, closeIterator, readIteratorResult, restoreSandboxIterator } from "./iteration.js";
|
|
30
30
|
import { assertCollectionMutable } from "./running-state.js";
|
|
31
31
|
import { getGeneratorMember } from "./methods/generator.js";
|
|
32
|
+
import { getGeneratorProperties } from "./generator-properties.js";
|
|
32
33
|
import { getRegexMember, setRegexMember } from "./methods/regex.js";
|
|
33
34
|
import { bindPattern } from "./patterns.js";
|
|
34
35
|
import { callStringMethod, getStringMember, isStringMethodName, validateStringMethodArguments } from "./methods/string.js";
|
|
@@ -1494,7 +1495,7 @@ function forInKeys(object, budget) {
|
|
|
1494
1495
|
if (depth > 0)
|
|
1495
1496
|
budget.visitNode();
|
|
1496
1497
|
assertSandboxDataDepth(depth++);
|
|
1497
|
-
const properties = isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current) ? materializeFunctionProperties(current) : isSandboxClosure(current) ? current.properties ?? {} : isSandboxRegex(current) ? getRegexProperties(current) : isSandboxMap(current) || isSandboxSet(current) ? getCollectionProperties(current) : current;
|
|
1498
|
+
const properties = isSandboxGenerator(current) ? getGeneratorProperties(current) : isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current) ? materializeFunctionProperties(current) : isSandboxClosure(current) ? current.properties ?? {} : isSandboxRegex(current) ? getRegexProperties(current) : isSandboxMap(current) || isSandboxSet(current) ? getCollectionProperties(current) : current;
|
|
1498
1499
|
for (const key of Object.getOwnPropertyNames(properties)) {
|
|
1499
1500
|
if (seen.has(key))
|
|
1500
1501
|
continue;
|
|
@@ -1515,7 +1516,7 @@ function hasForInProperty(object, key, budget) {
|
|
|
1515
1516
|
if (depth > 0)
|
|
1516
1517
|
budget.visitNode();
|
|
1517
1518
|
assertSandboxDataDepth(depth++);
|
|
1518
|
-
const properties = isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current) ? materializeFunctionProperties(current) : isSandboxClosure(current) ? current.properties ?? {} : isSandboxRegex(current) ? getRegexProperties(current) : isSandboxMap(current) || isSandboxSet(current) ? getCollectionProperties(current) : current;
|
|
1519
|
+
const properties = isSandboxGenerator(current) ? getGeneratorProperties(current) : isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current) ? materializeFunctionProperties(current) : isSandboxClosure(current) ? current.properties ?? {} : isSandboxRegex(current) ? getRegexProperties(current) : isSandboxMap(current) || isSandboxSet(current) ? getCollectionProperties(current) : current;
|
|
1519
1520
|
if (Object.hasOwn(properties, key))
|
|
1520
1521
|
return true;
|
|
1521
1522
|
}
|
|
@@ -2097,7 +2098,8 @@ function getPropertyValue(target, property, context, receiver = target) {
|
|
|
2097
2098
|
if (isSandboxCollectionIterator(target))
|
|
2098
2099
|
return getCollectionIteratorMember(target, property, context.budget);
|
|
2099
2100
|
if (isSandboxGenerator(target))
|
|
2100
|
-
return
|
|
2101
|
+
return hasExplicitSandboxPrototype(target)
|
|
2102
|
+
? undefined : getGeneratorMember(target, property, context.budget);
|
|
2101
2103
|
if (isSandboxClosure(target))
|
|
2102
2104
|
return getClosureMemberValue(target, property, context);
|
|
2103
2105
|
if (isSandboxPromise(target))
|
|
@@ -2384,7 +2386,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
2384
2386
|
return evaluatePrimitiveMemberCall(node, "Set", member.property, getSetMember(member.object, member.property, createSetMethodOptions(context)), context);
|
|
2385
2387
|
}
|
|
2386
2388
|
if (isSandboxGenerator(member.object)) {
|
|
2387
|
-
const memberValue =
|
|
2389
|
+
const memberValue = await getPropertyValue(member.object, member.property, context);
|
|
2388
2390
|
if (memberValue === undefined) {
|
|
2389
2391
|
throw new TypeError(`Generator#${String(member.property)} is not a supported method.`);
|
|
2390
2392
|
}
|
|
@@ -2662,7 +2664,7 @@ function hasSandboxProperty(value, key, context) {
|
|
|
2662
2664
|
return typeof key === "symbol" ? false : hasHostObjectMember(current, String(key));
|
|
2663
2665
|
if (hasOwnSandboxProperty(current, key, false))
|
|
2664
2666
|
return true;
|
|
2665
|
-
if (!isSandboxDate(current) && !isSandboxRegex(current) && !isSandboxMap(current) && !isSandboxSet(current) && !((isGuestClosure(current) || Array.isArray(current)) && hasExplicitSandboxPrototype(current)) &&
|
|
2667
|
+
if (!isSandboxDate(current) && !isSandboxRegex(current) && !isSandboxMap(current) && !isSandboxSet(current) && !((isGuestClosure(current) || isSandboxGenerator(current) || Array.isArray(current)) && hasExplicitSandboxPrototype(current)) &&
|
|
2666
2668
|
(Array.isArray(current) || !isPlainSandboxObject(current) ||
|
|
2667
2669
|
isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current) || isSandboxRegExpIterator(current))) {
|
|
2668
2670
|
return getPropertyValue(current, key, context) !== undefined;
|
|
@@ -2941,6 +2943,8 @@ export function setSandboxProperty(target, property, value, budget, checkInherit
|
|
|
2941
2943
|
target = materializeFunctionProperties(target);
|
|
2942
2944
|
if (isSandboxPromise(target))
|
|
2943
2945
|
target = getPromiseProperties(target);
|
|
2946
|
+
if (isSandboxGenerator(target))
|
|
2947
|
+
target = getGeneratorProperties(target);
|
|
2944
2948
|
if (isSandboxMap(target) || isSandboxSet(target))
|
|
2945
2949
|
target = getCollectionProperties(target);
|
|
2946
2950
|
if (isFloat32Array(target)) {
|
|
@@ -2977,7 +2981,7 @@ export function setSandboxProperty(target, property, value, budget, checkInherit
|
|
|
2977
2981
|
for (let prototype = getSandboxPrototype(prototypeOwner, budget); prototype !== null; prototype = getSandboxPrototype(prototype, budget)) {
|
|
2978
2982
|
budget.visitNode();
|
|
2979
2983
|
assertSandboxDataDepth(depth++);
|
|
2980
|
-
const properties = isSandboxClosure(prototype) ? prototype.properties : prototype;
|
|
2984
|
+
const properties = isSandboxGenerator(prototype) ? getGeneratorProperties(prototype) : isSandboxClosure(prototype) ? prototype.properties : prototype;
|
|
2981
2985
|
const inherited = properties === undefined ? undefined : Object.getOwnPropertyDescriptor(properties, key);
|
|
2982
2986
|
if (inherited === undefined)
|
|
2983
2987
|
continue;
|
|
@@ -2997,7 +3001,7 @@ function setSuperProperty(base, receiver, key, value, context) {
|
|
|
2997
3001
|
for (let current = base; current !== null; current = getSandboxPrototype(current, budget)) {
|
|
2998
3002
|
budget.visitNode();
|
|
2999
3003
|
assertSandboxDataDepth(depth++);
|
|
3000
|
-
const properties = isSandboxClosure(current) ? current.properties : current;
|
|
3004
|
+
const properties = isSandboxGenerator(current) ? getGeneratorProperties(current) : isSandboxClosure(current) ? current.properties : current;
|
|
3001
3005
|
const descriptor = properties === undefined ? undefined : Object.getOwnPropertyDescriptor(properties, key);
|
|
3002
3006
|
if (descriptor === undefined)
|
|
3003
3007
|
continue;
|
|
@@ -3020,6 +3024,8 @@ export function deleteSandboxProperty(target, property) {
|
|
|
3020
3024
|
target = getRegexProperties(target);
|
|
3021
3025
|
if (isSandboxPromise(target))
|
|
3022
3026
|
target = getPromiseProperties(target);
|
|
3027
|
+
if (isSandboxGenerator(target))
|
|
3028
|
+
target = getGeneratorProperties(target);
|
|
3023
3029
|
if (isSandboxMap(target) || isSandboxSet(target))
|
|
3024
3030
|
target = getCollectionProperties(target);
|
|
3025
3031
|
if (Array.isArray(target)) {
|
|
@@ -31,8 +31,9 @@ export async function restoreSandboxIterator(snapshot, budget, context, signal)
|
|
|
31
31
|
return asyncFromSyncIterator(await restoreSandboxIterator(snapshot.inner, budget, context, signal), budget, signal, context);
|
|
32
32
|
if (Array.isArray(snapshot.value))
|
|
33
33
|
return arrayIterator(snapshot.value, context, budget, snapshot.index);
|
|
34
|
-
const iterator = isSandboxGenerator(snapshot.value)
|
|
35
|
-
?
|
|
34
|
+
const iterator = isSandboxGenerator(snapshot.value)
|
|
35
|
+
? { ...generatorObjectIterator(snapshot.value, budget, context),
|
|
36
|
+
...(snapshot.value.async ? { asyncProtocol: true } : {}) }
|
|
36
37
|
: getSandboxIterator(snapshot.value, budget, context);
|
|
37
38
|
if (iterator === undefined)
|
|
38
39
|
throw new TypeError("Invalid builtin iterator snapshot.");
|
|
@@ -49,6 +50,12 @@ export async function acquireSandboxIterator(value, budget, context, asyncProtoc
|
|
|
49
50
|
: getSandboxIterator(value, budget, context);
|
|
50
51
|
if (getSandboxPropertyDescriptor(value, key, budget) === undefined &&
|
|
51
52
|
!(isSandboxRegExpIterator(value) && !asyncProtocol && getSandboxPropertyDescriptor(value, "next", budget) !== undefined)) {
|
|
53
|
+
if (isSandboxGenerator(value)) {
|
|
54
|
+
if (hasExplicitSandboxPrototype(value))
|
|
55
|
+
return undefined;
|
|
56
|
+
if ((value.async === true) === asyncProtocol && getSandboxPropertyDescriptor(value, "next", budget) !== undefined)
|
|
57
|
+
return guestIterator(value, await context.getProperty(value, "next"), asyncProtocol, budget, context, signal);
|
|
58
|
+
}
|
|
52
59
|
if (!asyncProtocol && Array.isArray(value) && getSandboxPrototype(value, budget) !== null)
|
|
53
60
|
return undefined;
|
|
54
61
|
if (!asyncProtocol)
|
|
@@ -130,7 +137,8 @@ export async function readIteratorResult(iterator, result, property) {
|
|
|
130
137
|
}
|
|
131
138
|
export function getSandboxAsyncIterator(value, budget, context, signal) {
|
|
132
139
|
if (isSandboxGenerator(value) && value.async) {
|
|
133
|
-
return
|
|
140
|
+
return hasExplicitSandboxPrototype(value) ? undefined
|
|
141
|
+
: { ...generatorObjectIterator(value, budget, context), asyncProtocol: true };
|
|
134
142
|
}
|
|
135
143
|
if (value !== null &&
|
|
136
144
|
(typeof value === "object" || typeof value === "function") &&
|
|
@@ -288,7 +296,7 @@ export function getSandboxIterator(value, budget, context) {
|
|
|
288
296
|
return syncIterator(Float32Array.prototype.values.call(value));
|
|
289
297
|
}
|
|
290
298
|
if (isSandboxGenerator(value)) {
|
|
291
|
-
return value.async ? undefined :
|
|
299
|
+
return value.async || hasExplicitSandboxPrototype(value) ? undefined : generatorObjectIterator(value, budget, context);
|
|
292
300
|
}
|
|
293
301
|
if (typeof value === "string") {
|
|
294
302
|
const iterator = value[Symbol.iterator]();
|
|
@@ -373,6 +381,31 @@ function collectionIterator(collection, value) {
|
|
|
373
381
|
return adapter;
|
|
374
382
|
}
|
|
375
383
|
const asyncGeneratorRequests = new WeakMap();
|
|
384
|
+
function generatorObjectIterator(generator, budget, context) {
|
|
385
|
+
const iterator = generatorIterator(generator, budget, context);
|
|
386
|
+
if (context?.getProperty === undefined)
|
|
387
|
+
return iterator;
|
|
388
|
+
return {
|
|
389
|
+
...iterator,
|
|
390
|
+
getOperation: async (method) => {
|
|
391
|
+
if (method === "next" || (!hasExplicitSandboxPrototype(generator) &&
|
|
392
|
+
getSandboxPropertyDescriptor(generator, method, budget) === undefined))
|
|
393
|
+
return iterator[method];
|
|
394
|
+
const operation = await context.getProperty(generator, method);
|
|
395
|
+
if (operation === undefined || operation === null)
|
|
396
|
+
return undefined;
|
|
397
|
+
if (!isSandboxClosure(operation))
|
|
398
|
+
throw new TypeError("Iterator operation must be callable.");
|
|
399
|
+
return async (...args) => {
|
|
400
|
+
const result = await invokeBuiltinClosure(operation, args, budget ?? new Budget(), context, generator);
|
|
401
|
+
return (generator.async ? await awaitSandboxValue(result, undefined, budget, context) : result);
|
|
402
|
+
};
|
|
403
|
+
},
|
|
404
|
+
readResultProperty: async (result, property) => ({
|
|
405
|
+
value: await context.getProperty(result, property)
|
|
406
|
+
})
|
|
407
|
+
};
|
|
408
|
+
}
|
|
376
409
|
export function generatorIterator(generator, budget, context) {
|
|
377
410
|
const invoke = async (method, value) => {
|
|
378
411
|
const leaveRunning = enterRunningState(generator);
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { type SandboxClosure, type SandboxValue } from "../values.js";
|
|
1
|
+
import { type SandboxCallContext, type SandboxClosure, type SandboxValue } from "../values.js";
|
|
2
2
|
import type { Budget } from "../budget.js";
|
|
3
3
|
export type FunctionMethodOptions = {
|
|
4
4
|
budget?: Budget;
|
|
5
5
|
callClosure: (closure: SandboxClosure, args: readonly SandboxValue[], stack: readonly string[], thisValue: SandboxValue, construct?: boolean, newTarget?: SandboxClosure) => Promise<SandboxValue> | SandboxValue;
|
|
6
6
|
};
|
|
7
|
+
type FunctionMethodName = "apply" | "bind" | "call" | "toString";
|
|
7
8
|
export declare function getFunctionMember(target: SandboxClosure, property: string | number, options: FunctionMethodOptions): SandboxValue | undefined;
|
|
9
|
+
export declare function callFunctionMethod(target: SandboxValue, methodName: FunctionMethodName, args: readonly SandboxValue[], options: FunctionMethodOptions, stack: readonly string[], context?: SandboxCallContext): Promise<SandboxValue> | SandboxValue;
|
|
10
|
+
export {};
|
|
@@ -22,7 +22,7 @@ export function getFunctionMember(target, property, options) {
|
|
|
22
22
|
else if (Object.hasOwn(current, String(property))) {
|
|
23
23
|
return current[String(property)];
|
|
24
24
|
}
|
|
25
|
-
if (isSandboxClosure(current) && !hasExplicitSandboxPrototype(current))
|
|
25
|
+
if (isSandboxClosure(current) && !hasExplicitSandboxPrototype(current) && getSandboxPrototype(current, options.budget) === null)
|
|
26
26
|
break;
|
|
27
27
|
current = getSandboxPrototype(current, options.budget);
|
|
28
28
|
if (current !== null) {
|
|
@@ -47,7 +47,7 @@ export function getFunctionMember(target, property, options) {
|
|
|
47
47
|
function isFunctionMethodName(property) {
|
|
48
48
|
return typeof property === "string" && functionMethodNames.has(property);
|
|
49
49
|
}
|
|
50
|
-
function callFunctionMethod(target, methodName, args, options, stack, context) {
|
|
50
|
+
export function callFunctionMethod(target, methodName, args, options, stack, context) {
|
|
51
51
|
if (!isSandboxClosure(target)) {
|
|
52
52
|
throw new TypeError(`Function#${methodName} requires a callable receiver.`);
|
|
53
53
|
}
|
|
@@ -7,6 +7,7 @@ export declare function getGuestFunctionProperties(closure: SandboxClosure): San
|
|
|
7
7
|
export declare function materializeFunctionProperties(closure: SandboxClosure): SandboxObject;
|
|
8
8
|
export declare function getGuestFunctionProperty(closure: SandboxClosure, key: PropertyKey): SandboxValue;
|
|
9
9
|
export declare function installObjectPrototype(budget: Budget, prototype: SandboxObject, constructor: SandboxClosure): void;
|
|
10
|
+
export declare function installFunctionPrototype(budget: Budget, prototype: SandboxClosure): void;
|
|
10
11
|
export declare function installBoxedPrototype(budget: Budget, prototype: SandboxObject, constructor: SandboxClosure, kind?: BoxedKind): void;
|
|
11
12
|
export declare function getBoxedPrototype(value: BoxedPrimitive, budget: Budget): SandboxObject | undefined;
|
|
12
13
|
export declare function installRegexPrototype(budget: Budget, prototype: SandboxObject, constructor: SandboxClosure): void;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { assertSandboxDataDepth } from "../graph-depth.js";
|
|
2
|
+
import { getGeneratorProperties } from "./generator-properties.js";
|
|
3
|
+
import { runResources } from "./resources.js";
|
|
2
4
|
import { getIntrinsicIdentity, registerBuiltinIdentities, releaseIntrinsicIdentities } from "./intrinsics.js";
|
|
3
5
|
import { releaseTemplateObjects } from "./template-objects.js";
|
|
4
6
|
import { isSandboxDate } from "./date.js";
|
|
@@ -8,6 +10,7 @@ import { boxedValue, isSandboxBox } from "./boxed.js";
|
|
|
8
10
|
import { isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, getPromiseProperties, isSandboxRegex, getRegexProperties, getCollectionProperties, isSandboxSet } from "./values.js";
|
|
9
11
|
const guestClosures = new WeakSet();
|
|
10
12
|
const functionProperties = new WeakMap();
|
|
13
|
+
const functionPropertyRevisions = new WeakMap();
|
|
11
14
|
const prototypes = new WeakMap();
|
|
12
15
|
const intrinsicPrototypes = new WeakMap();
|
|
13
16
|
const boxedPrototypes = new WeakMap();
|
|
@@ -16,6 +19,7 @@ const collectionPrototypes = new WeakMap();
|
|
|
16
19
|
const promisePrototypes = new WeakMap();
|
|
17
20
|
const datePrototypes = new WeakMap();
|
|
18
21
|
const arrayPrototypes = new WeakMap();
|
|
22
|
+
const functionPrototypes = new WeakMap();
|
|
19
23
|
const initialArrayMethods = new WeakMap();
|
|
20
24
|
const initialRegexDescriptors = new WeakMap();
|
|
21
25
|
const intrinsicPrototypeRoots = new WeakMap();
|
|
@@ -53,9 +57,26 @@ export function materializeFunctionProperties(closure) {
|
|
|
53
57
|
descriptorObjects.add(prototype);
|
|
54
58
|
Object.defineProperty(properties, "prototype", { value: prototype, writable: true });
|
|
55
59
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
// Never expose the raw table: native callers must invalidate captures too.
|
|
61
|
+
const state = { revision: 0 };
|
|
62
|
+
const tracked = new Proxy(properties, {
|
|
63
|
+
defineProperty(target, key, descriptor) {
|
|
64
|
+
const changed = Reflect.defineProperty(target, key, descriptor);
|
|
65
|
+
if (changed)
|
|
66
|
+
state.revision++;
|
|
67
|
+
return changed;
|
|
68
|
+
},
|
|
69
|
+
deleteProperty(target, key) {
|
|
70
|
+
const changed = Reflect.deleteProperty(target, key);
|
|
71
|
+
if (changed)
|
|
72
|
+
state.revision++;
|
|
73
|
+
return changed;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
functionPropertyRevisions.set(tracked, state);
|
|
77
|
+
descriptorObjects.add(tracked);
|
|
78
|
+
functionProperties.set(closure, tracked);
|
|
79
|
+
return tracked;
|
|
59
80
|
}
|
|
60
81
|
export function getGuestFunctionProperty(closure, key) {
|
|
61
82
|
let properties = functionProperties.get(closure);
|
|
@@ -79,6 +100,12 @@ export function installObjectPrototype(budget, prototype, constructor) {
|
|
|
79
100
|
intrinsicPrototypes.set(budget, prototype);
|
|
80
101
|
registerIntrinsicPrototype(budget, prototype, constructor);
|
|
81
102
|
}
|
|
103
|
+
export function installFunctionPrototype(budget, prototype) {
|
|
104
|
+
functionPrototypes.set(budget, prototype);
|
|
105
|
+
registerBuiltinIdentities(budget, { "%FunctionPrototype%": prototype });
|
|
106
|
+
registerIntrinsicFunction(budget, prototype);
|
|
107
|
+
registerIntrinsicObject(budget, materializeFunctionProperties(prototype));
|
|
108
|
+
}
|
|
82
109
|
export function installBoxedPrototype(budget, prototype, constructor, kind = typeof boxedValue(prototype)) {
|
|
83
110
|
let state = boxedPrototypes.get(budget);
|
|
84
111
|
if (state === undefined)
|
|
@@ -181,6 +208,9 @@ function trackIntrinsicState(budget, root, owner, targets) {
|
|
|
181
208
|
}))
|
|
182
209
|
.map((record) => ({
|
|
183
210
|
...record,
|
|
211
|
+
revision: functionPropertyRevisions.get(record.value),
|
|
212
|
+
capturedRevision: -1,
|
|
213
|
+
captured: [],
|
|
184
214
|
extensible: Object.isExtensible(record.value),
|
|
185
215
|
descriptors: new Map(Reflect.ownKeys(record.value).map(key => [key, Object.getOwnPropertyDescriptor(record.value, key)]))
|
|
186
216
|
}));
|
|
@@ -206,16 +236,24 @@ function trackIntrinsicState(budget, root, owner, targets) {
|
|
|
206
236
|
budget.setRetainedValues(root, () => {
|
|
207
237
|
// Capture every change before measurement invokes retained-value callbacks.
|
|
208
238
|
const retained = [];
|
|
209
|
-
for (const
|
|
239
|
+
for (const record of records) {
|
|
240
|
+
const { target, value, descriptors, prototype: parent, revision } = record;
|
|
210
241
|
const currentPrototype = getSandboxPrototype(target);
|
|
211
242
|
if (currentPrototype !== parent)
|
|
212
243
|
retained.push(currentPrototype);
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
244
|
+
if (revision === undefined || revision.revision !== record.capturedRevision) {
|
|
245
|
+
const captured = [];
|
|
246
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
247
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
248
|
+
if (unchanged(descriptors.get(key), descriptor))
|
|
249
|
+
continue;
|
|
250
|
+
captured.push(key, descriptor.value, ...retainedAccessorClosures(descriptor));
|
|
251
|
+
}
|
|
252
|
+
record.captured = captured;
|
|
253
|
+
record.capturedRevision = revision?.revision ?? -1;
|
|
218
254
|
}
|
|
255
|
+
for (const item of record.captured)
|
|
256
|
+
retained.push(item);
|
|
219
257
|
}
|
|
220
258
|
return retained;
|
|
221
259
|
});
|
|
@@ -232,12 +270,15 @@ export function releaseObjectPrototype(budget) {
|
|
|
232
270
|
promisePrototypes.delete(budget);
|
|
233
271
|
datePrototypes.delete(budget);
|
|
234
272
|
arrayPrototypes.delete(budget);
|
|
273
|
+
functionPrototypes.delete(budget);
|
|
235
274
|
initialRegexDescriptors.delete(budget);
|
|
236
275
|
intrinsicPrototypes.delete(budget);
|
|
237
276
|
}
|
|
238
277
|
export function getSandboxPrototype(value, budget) {
|
|
239
278
|
if (prototypes.has(value))
|
|
240
279
|
return prototypes.get(value) ?? null;
|
|
280
|
+
if (budget !== undefined && isGuestClosure(value) && runResources.getStore()?.functionSourceText !== false)
|
|
281
|
+
return functionPrototypes.get(budget) ?? null;
|
|
241
282
|
if (budget !== undefined && Array.isArray(value))
|
|
242
283
|
return arrayPrototypes.get(budget) ?? null;
|
|
243
284
|
if (budget !== undefined && isSandboxDate(value))
|
|
@@ -273,9 +314,14 @@ export function getSandboxPropertyDescriptor(value, key, budget) {
|
|
|
273
314
|
let depth = 0;
|
|
274
315
|
while (typeof current === "object" &&
|
|
275
316
|
current !== null &&
|
|
276
|
-
(Array.isArray(current) || isSandboxDate(current) || isSandboxPromise(current) || isSandboxRegex(current) || isSandboxMap(current) || isSandboxSet(current) || isPrototypeRecord(current))) {
|
|
277
|
-
const properties =
|
|
317
|
+
(Array.isArray(current) || isSandboxGenerator(current) || isSandboxDate(current) || isSandboxPromise(current) || isSandboxRegex(current) || isSandboxMap(current) || isSandboxSet(current) || isPrototypeRecord(current))) {
|
|
318
|
+
const properties = isSandboxGenerator(current) ? getGeneratorProperties(current) : isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current)
|
|
319
|
+
? key === "prototype" && current.construct !== undefined && current.boundTarget === undefined
|
|
320
|
+
? materializeFunctionProperties(current) : getGuestFunctionProperties(current)
|
|
278
321
|
: isSandboxRegex(current) ? getRegexProperties(current) : isSandboxMap(current) || isSandboxSet(current) ? getCollectionProperties(current) : current;
|
|
322
|
+
if (properties === undefined && isGuestClosure(current) && (key === "name" || key === "length"))
|
|
323
|
+
return { value: key === "name" ? current.name ?? "" : current.length ?? 0,
|
|
324
|
+
writable: false, enumerable: false, configurable: true };
|
|
279
325
|
const descriptor = properties === undefined ? undefined : Object.getOwnPropertyDescriptor(properties, key);
|
|
280
326
|
if (descriptor !== undefined)
|
|
281
327
|
return descriptor;
|
|
@@ -297,6 +343,11 @@ export function getSandboxDataProperty(value, key, budget) {
|
|
|
297
343
|
return Object.getOwnPropertyDescriptor(getRegexProperties(current), key)?.value;
|
|
298
344
|
if (isSandboxPromise(current))
|
|
299
345
|
return Object.getOwnPropertyDescriptor(getPromiseProperties(current), key)?.value;
|
|
346
|
+
if (isSandboxGenerator(current)) {
|
|
347
|
+
const descriptor = Object.getOwnPropertyDescriptor(getGeneratorProperties(current), key);
|
|
348
|
+
if (descriptor !== undefined)
|
|
349
|
+
return descriptor.value;
|
|
350
|
+
}
|
|
300
351
|
if (isSandboxMap(current) || isSandboxSet(current))
|
|
301
352
|
return Object.getOwnPropertyDescriptor(getCollectionProperties(current), key)?.value;
|
|
302
353
|
if (isGuestClosure(current)) {
|
|
@@ -313,10 +364,9 @@ export function getSandboxDataProperty(value, key, budget) {
|
|
|
313
364
|
if (isSandboxMap(current) ||
|
|
314
365
|
isSandboxSet(current) ||
|
|
315
366
|
isSandboxPromise(current) ||
|
|
316
|
-
isSandboxRegex(current)
|
|
317
|
-
isSandboxGenerator(current))
|
|
367
|
+
isSandboxRegex(current))
|
|
318
368
|
return undefined;
|
|
319
|
-
if (!isSandboxClosure(current) && Object.hasOwn(current, key))
|
|
369
|
+
if (!isSandboxClosure(current) && !isSandboxGenerator(current) && Object.hasOwn(current, key))
|
|
320
370
|
return current[key];
|
|
321
371
|
current = getSandboxPrototype(current, budget);
|
|
322
372
|
if (current !== null) {
|
|
@@ -330,8 +380,8 @@ export function setSandboxPrototype(value, prototype, budget) {
|
|
|
330
380
|
if (budget !== undefined && intrinsicPrototypes.get(budget) === value && prototype !== null) {
|
|
331
381
|
throw new TypeError("Object.prototype has an immutable null prototype.");
|
|
332
382
|
}
|
|
333
|
-
if ((!Array.isArray(value) && !isSandboxDate(value) && !isSandboxPromise(value) && !isSandboxRegex(value) && !isSandboxMap(value) && !isSandboxSet(value) && !isPrototypeRecord(value)) ||
|
|
334
|
-
(prototype !== null && !Array.isArray(prototype) && !isSandboxDate(prototype) && !isSandboxPromise(prototype) && !isSandboxRegex(prototype) && !isSandboxMap(prototype) && !isSandboxSet(prototype) && !isPrototypeRecord(prototype))) {
|
|
383
|
+
if ((!Array.isArray(value) && !isSandboxGenerator(value) && !isSandboxDate(value) && !isSandboxPromise(value) && !isSandboxRegex(value) && !isSandboxMap(value) && !isSandboxSet(value) && !isPrototypeRecord(value)) ||
|
|
384
|
+
(prototype !== null && !Array.isArray(prototype) && !isSandboxGenerator(prototype) && !isSandboxDate(prototype) && !isSandboxPromise(prototype) && !isSandboxRegex(prototype) && !isSandboxMap(prototype) && !isSandboxSet(prototype) && !isPrototypeRecord(prototype))) {
|
|
335
385
|
throw new TypeError("Prototype links require supported sandbox objects.");
|
|
336
386
|
}
|
|
337
387
|
if (getSandboxPrototype(value, budget) === prototype) {
|
|
@@ -340,7 +390,7 @@ export function setSandboxPrototype(value, prototype, budget) {
|
|
|
340
390
|
prototypes.set(value, null);
|
|
341
391
|
return;
|
|
342
392
|
}
|
|
343
|
-
if (!Object.isExtensible(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value)) {
|
|
393
|
+
if (!Object.isExtensible(isSandboxGenerator(value) ? getGeneratorProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value)) {
|
|
344
394
|
throw new TypeError("Cannot change the prototype of a non-extensible object.");
|
|
345
395
|
}
|
|
346
396
|
let depth = 0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
2
|
+
import { getGeneratorProperties } from "./generator-properties.js";
|
|
2
3
|
import { readPropertyDescriptor } from "./accessors.js";
|
|
3
4
|
import { dateString, dateTime, isSandboxDate } from "./date.js";
|
|
4
5
|
import { invokeBuiltinClosure } from "./builtin-call.js";
|
|
@@ -115,7 +116,7 @@ function conversionHook(value, name, budget, context) {
|
|
|
115
116
|
((Array.isArray(value) && getSandboxPrototype(value, budget) === null) ||
|
|
116
117
|
isFloat32Array(value) ||
|
|
117
118
|
sandboxErrorTypes.has(value) ||
|
|
118
|
-
isSandboxClosure(value) ||
|
|
119
|
+
(isSandboxClosure(value) && getSandboxPrototype(value, budget) === null) ||
|
|
119
120
|
isSandboxMap(value) ||
|
|
120
121
|
isSandboxSet(value) ||
|
|
121
122
|
isSandboxCollectionIterator(value) ||
|
|
@@ -127,7 +128,7 @@ function conversionHook(value, name, budget, context) {
|
|
|
127
128
|
let current = value;
|
|
128
129
|
let depth = 0;
|
|
129
130
|
while (current !== null) {
|
|
130
|
-
const properties = isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current) ? getGuestFunctionProperties(current)
|
|
131
|
+
const properties = isSandboxGenerator(current) ? getGeneratorProperties(current) : isSandboxPromise(current) ? getPromiseProperties(current) : isGuestClosure(current) ? getGuestFunctionProperties(current)
|
|
131
132
|
: isSandboxRegex(current) ? getRegexProperties(current)
|
|
132
133
|
: isSandboxMap(current) || isSandboxSet(current) ? getCollectionProperties(current) : current;
|
|
133
134
|
const descriptor = properties === undefined ? undefined : Object.getOwnPropertyDescriptor(properties, name);
|