poe-code 14.0.74 → 14.0.76
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 +1283 -144
- 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-YEZOXLY4.js → chunk-UZYQWFMY.js} +1233 -143
- package/packages/safe-js/dist/chunks/chunk-UZYQWFMY.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-2J6W3YGB.js → chunk-VD2AS4E4.js} +2 -2
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/index.js.map +1 -1
- package/packages/safe-js/dist/interp/bigint-operators.d.ts +3 -0
- package/packages/safe-js/dist/interp/bigint-operators.js +62 -0
- package/packages/safe-js/dist/interp/boxed.d.ts +2 -2
- package/packages/safe-js/dist/interp/boxed.js +4 -1
- package/packages/safe-js/dist/interp/globals/bigint.d.ts +2 -0
- package/packages/safe-js/dist/interp/globals/bigint.js +85 -0
- package/packages/safe-js/dist/interp/globals/console-json.js +57 -24
- package/packages/safe-js/dist/interp/globals/object-array.js +1 -1
- package/packages/safe-js/dist/interp/globals/regex.js +108 -2
- package/packages/safe-js/dist/interp/globals.d.ts +1 -0
- package/packages/safe-js/dist/interp/globals.js +2 -0
- package/packages/safe-js/dist/interp/host-bridge.js +2 -0
- package/packages/safe-js/dist/interp/interpreter.js +59 -12
- package/packages/safe-js/dist/interp/iteration.js +5 -2
- package/packages/safe-js/dist/interp/methods/number.js +1 -1
- package/packages/safe-js/dist/interp/methods/regex-split.d.ts +3 -0
- package/packages/safe-js/dist/interp/methods/regex-split.js +102 -0
- package/packages/safe-js/dist/interp/methods/regex.d.ts +1 -1
- package/packages/safe-js/dist/interp/methods/regex.js +16 -5
- package/packages/safe-js/dist/interp/methods/regexp-iterator.d.ts +5 -1
- package/packages/safe-js/dist/interp/methods/regexp-iterator.js +59 -7
- package/packages/safe-js/dist/interp/methods/string.js +9 -9
- package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
- package/packages/safe-js/dist/interp/object-model.js +4 -1
- package/packages/safe-js/dist/interp/regex/compile-guard.js +26 -4
- package/packages/safe-js/dist/interp/regex/engine.d.ts +4 -0
- package/packages/safe-js/dist/interp/regex/engine.js +230 -30
- package/packages/safe-js/dist/interp/regex/parse.d.ts +42 -4
- package/packages/safe-js/dist/interp/regex/parse.js +429 -25
- package/packages/safe-js/dist/interp/regexp-iterator.d.ts +4 -2
- package/packages/safe-js/dist/interp/regexp-iterator.js +6 -1
- package/packages/safe-js/dist/interp/string-coercion.d.ts +1 -1
- package/packages/safe-js/dist/interp/string-coercion.js +8 -3
- package/packages/safe-js/dist/interp/values.d.ts +1 -1
- package/packages/safe-js/dist/interp/values.js +10 -3
- package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +2 -0
- package/packages/safe-js/dist/lint/rules/AS-missing-async.js +2 -0
- package/packages/safe-js/dist/lint/rules/known-globals.d.ts +1 -1
- package/packages/safe-js/dist/lint/rules/known-globals.js +1 -0
- package/packages/safe-js/dist/parse/parser.d.ts +6 -1
- package/packages/safe-js/dist/parse/parser.js +8 -0
- package/packages/safe-js/dist/parse/tokenizer.js +12 -4
- package/packages/safe-js/dist/parse.d.ts +1 -1
- package/packages/safe-js/dist/snapshot/bigint.d.ts +1 -0
- package/packages/safe-js/dist/snapshot/bigint.js +14 -0
- package/packages/safe-js/dist/snapshot/dump-format.js +12 -2
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +6 -0
- package/packages/safe-js/dist/snapshot/replay-data.js +23 -5
- package/packages/safe-js/dist/snapshot/restore.js +10 -2
- package/packages/safe-js/dist/snapshot/serialize.d.ts +4 -1
- package/packages/safe-js/dist/snapshot/serialize.js +6 -1
- package/packages/safe-js/dist/snapshot/validation.js +27 -0
- package/packages/safe-js/dist/chunks/chunk-YEZOXLY4.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-2J6W3YGB.js.map → chunk-VD2AS4E4.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Budget } from "./budget.js";
|
|
2
2
|
import { type SandboxCallContext, type SandboxPrimitive, type SandboxValue } from "./values.js";
|
|
3
|
-
export declare function sandboxNumber(value: SandboxValue, budget: Budget, context?: SandboxCallContext): number | Promise<number>;
|
|
3
|
+
export declare function sandboxNumber(value: SandboxValue, budget: Budget, context?: SandboxCallContext, allowBigInt?: boolean): number | Promise<number>;
|
|
4
4
|
export declare function sandboxString(value: SandboxValue, budget: Budget, context?: SandboxCallContext, joining?: Set<object>): string | Promise<string>;
|
|
5
5
|
export declare function joinSandboxArray(value: SandboxValue & object, length: number, separator: string, budget: Budget, context?: SandboxCallContext, joining?: Set<object>): Promise<string>;
|
|
6
6
|
export declare function objectToPrimitive(value: SandboxValue & object, budget: Budget, context: SandboxCallContext | undefined, joining: Set<object>, hint: "string" | "number" | "default", ordinary?: boolean): Promise<SandboxPrimitive>;
|
|
@@ -17,13 +17,18 @@ import { isSandboxClosure, isSandboxPromise, isSandboxMap, isSandboxSet, isSandb
|
|
|
17
17
|
const defaultStringHook = Symbol("defaultStringHook");
|
|
18
18
|
const defaultValueHook = Symbol("defaultValueHook");
|
|
19
19
|
const joiningArrays = new WeakSet();
|
|
20
|
-
export function sandboxNumber(value, budget, context) {
|
|
20
|
+
export function sandboxNumber(value, budget, context, allowBigInt = false) {
|
|
21
|
+
const convert = (primitive) => {
|
|
22
|
+
if (typeof primitive === "bigint" && !allowBigInt)
|
|
23
|
+
throw new TypeError("Cannot convert a BigInt value to a number");
|
|
24
|
+
return Number(primitive);
|
|
25
|
+
};
|
|
21
26
|
if (value === null || typeof value !== "object") {
|
|
22
27
|
if (typeof value === "function")
|
|
23
28
|
throw new TypeError("Expected a sandbox value.");
|
|
24
|
-
return
|
|
29
|
+
return convert(value);
|
|
25
30
|
}
|
|
26
|
-
return objectToPrimitive(value, budget, context, new Set(), "number").then(
|
|
31
|
+
return objectToPrimitive(value, budget, context, new Set(), "number").then(convert);
|
|
27
32
|
}
|
|
28
33
|
export function sandboxString(value, budget, context, joining = new Set()) {
|
|
29
34
|
if (typeof value === "symbol")
|
|
@@ -15,7 +15,7 @@ declare const sandboxPromiseBrand: unique symbol;
|
|
|
15
15
|
declare const sandboxRegexBrand: unique symbol;
|
|
16
16
|
declare const sandboxRegexPattern: unique symbol;
|
|
17
17
|
declare const sandboxRetainedValues: unique symbol;
|
|
18
|
-
export type SandboxPrimitive = string | number | boolean | symbol | null | undefined;
|
|
18
|
+
export type SandboxPrimitive = string | number | bigint | boolean | symbol | null | undefined;
|
|
19
19
|
export type SandboxValue = SandboxPrimitive | Date | Float32Array | SandboxObject | SandboxArray | SandboxClosure | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | SandboxMap | SandboxSet | SandboxPromise | SandboxRegex;
|
|
20
20
|
export type SandboxObject = {
|
|
21
21
|
[key: string]: SandboxValue;
|
|
@@ -19,7 +19,7 @@ import { invokeCancelableClosure, readPromiseCancellation, registerPromiseCancel
|
|
|
19
19
|
import { parseRegex } from "./regex/parse.js";
|
|
20
20
|
import { assertSandboxDataDepth } from "../graph-depth.js";
|
|
21
21
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
22
|
-
import { getGuestFunctionProperties, getSandboxPrototype, hasGuestObjectState, hasManagedDescriptors, isGuestClosure, isIntrinsicConstructor, registerGuestClosure } from "./object-model.js";
|
|
22
|
+
import { getGuestFunctionProperties, getSandboxPrototype, hasGuestObjectState, hasManagedDescriptors, hasNullObjectPrototype, isGuestClosure, isIntrinsicConstructor, registerGuestClosure, setSandboxPrototype } from "./object-model.js";
|
|
23
23
|
import { copySandboxArgumentProperties, createSandboxArguments, getSandboxArgumentEntries, isSandboxArguments } from "./arguments.js";
|
|
24
24
|
export { createSandboxArguments, isSandboxArguments } from "./arguments.js";
|
|
25
25
|
export { isSandboxMap, isSandboxSet } from "./collection-brands.js";
|
|
@@ -299,6 +299,10 @@ export function measureSandboxData(values, options = {}) {
|
|
|
299
299
|
const seenSymbols = new Set();
|
|
300
300
|
let usage = 0;
|
|
301
301
|
const visit = (value, depth = 0) => {
|
|
302
|
+
if (typeof value === "bigint") {
|
|
303
|
+
usage += value.toString(16).length;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
302
306
|
if (typeof value === "symbol") {
|
|
303
307
|
if (!seenSymbols.has(value)) {
|
|
304
308
|
seenSymbols.add(value);
|
|
@@ -612,7 +616,7 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
612
616
|
const copy = restoreSandboxRegExpIterator({ matcher: undefined, input: undefined, exhausted: true });
|
|
613
617
|
state.seen.set(value, copy);
|
|
614
618
|
const matcher = copyToSandbox(snapshot.matcher, state, `${path}.<matcher>`, true, depth + 1);
|
|
615
|
-
if (matcher !== undefined && !isSandboxRegex(matcher))
|
|
619
|
+
if (matcher !== undefined && (snapshot.global === undefined ? !isSandboxRegex(matcher) : matcher === null || typeof matcher !== "object"))
|
|
616
620
|
throw new TypeError("Invalid RegExp iterator matcher.");
|
|
617
621
|
restoreSandboxRegExpIterator({ ...snapshot, matcher }, copy);
|
|
618
622
|
for (const entry of getEnumerableObjectEntries(value, path)) {
|
|
@@ -781,6 +785,8 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
781
785
|
return existing;
|
|
782
786
|
}
|
|
783
787
|
const copy = createPlainObject(!cloneSandboxCollections || Object.getPrototypeOf(value) === null);
|
|
788
|
+
if (!state.structuredClone && hasNullObjectPrototype(value))
|
|
789
|
+
setSandboxPrototype(copy, null);
|
|
784
790
|
state.seen.set(value, copy);
|
|
785
791
|
const errorType = sandboxErrorTypes.get(value);
|
|
786
792
|
if (errorType !== undefined)
|
|
@@ -978,7 +984,7 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
978
984
|
if (existing !== undefined) {
|
|
979
985
|
return existing;
|
|
980
986
|
}
|
|
981
|
-
const copy = createPlainObject(Object.getPrototypeOf(value) === null);
|
|
987
|
+
const copy = createPlainObject(hasNullObjectPrototype(value) || Object.getPrototypeOf(value) === null);
|
|
982
988
|
state.seen.set(value, copy);
|
|
983
989
|
for (const entry of getEnumerableObjectEntries(value, path)) {
|
|
984
990
|
defineOwnDataProperty(copy, entry.key, copyFromSandbox(entry.value, state, joinPath(path, entry.key), options, depth + 1));
|
|
@@ -992,6 +998,7 @@ function isSandboxPrimitive(value) {
|
|
|
992
998
|
value === undefined ||
|
|
993
999
|
typeof value === "string" ||
|
|
994
1000
|
typeof value === "number" ||
|
|
1001
|
+
typeof value === "bigint" ||
|
|
995
1002
|
typeof value === "boolean" ||
|
|
996
1003
|
typeof value === "symbol");
|
|
997
1004
|
}
|
|
@@ -229,6 +229,7 @@ class ASAsyncNotNeededScanner {
|
|
|
229
229
|
case "MetaProperty":
|
|
230
230
|
case "NullLiteral":
|
|
231
231
|
case "NumericLiteral":
|
|
232
|
+
case "BigIntLiteral":
|
|
232
233
|
case "RegexLiteral":
|
|
233
234
|
case "StringLiteral":
|
|
234
235
|
case "UndefinedLiteral":
|
|
@@ -539,6 +540,7 @@ function expressionContainsAwait(node) {
|
|
|
539
540
|
case "MetaProperty":
|
|
540
541
|
case "NullLiteral":
|
|
541
542
|
case "NumericLiteral":
|
|
543
|
+
case "BigIntLiteral":
|
|
542
544
|
case "RegexLiteral":
|
|
543
545
|
case "StringLiteral":
|
|
544
546
|
case "ThisExpression":
|
|
@@ -213,6 +213,7 @@ class ASMissingAsyncScanner {
|
|
|
213
213
|
case "MetaProperty":
|
|
214
214
|
case "NullLiteral":
|
|
215
215
|
case "NumericLiteral":
|
|
216
|
+
case "BigIntLiteral":
|
|
216
217
|
case "RegexLiteral":
|
|
217
218
|
case "StringLiteral":
|
|
218
219
|
case "UndefinedLiteral":
|
|
@@ -509,6 +510,7 @@ function expressionContainsAwait(node) {
|
|
|
509
510
|
case "MetaProperty":
|
|
510
511
|
case "NullLiteral":
|
|
511
512
|
case "NumericLiteral":
|
|
513
|
+
case "BigIntLiteral":
|
|
512
514
|
case "RegexLiteral":
|
|
513
515
|
case "StringLiteral":
|
|
514
516
|
case "ThisExpression":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const KNOWN_RUNTIME_GLOBALS: readonly ["AggregateError", "Array", "Boolean", "Date", "Error", "Infinity", "isFinite", "isNaN", "JSON", "Map", "Float32Array", "Math", "NaN", "Number", "Object", "parseFloat", "parseInt", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "String", "Symbol", "structuredClone", "SyntaxError", "TypeError", "console"];
|
|
1
|
+
export declare const KNOWN_RUNTIME_GLOBALS: readonly ["AggregateError", "Array", "Boolean", "BigInt", "Date", "Error", "Infinity", "isFinite", "isNaN", "JSON", "Map", "Float32Array", "Math", "NaN", "Number", "Object", "parseFloat", "parseInt", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "String", "Symbol", "structuredClone", "SyntaxError", "TypeError", "console"];
|
|
@@ -26,6 +26,11 @@ export type NumericLiteral = BaseNode & {
|
|
|
26
26
|
raw: string;
|
|
27
27
|
value: number;
|
|
28
28
|
};
|
|
29
|
+
export type BigIntLiteral = BaseNode & {
|
|
30
|
+
type: "BigIntLiteral";
|
|
31
|
+
raw: string;
|
|
32
|
+
value: string;
|
|
33
|
+
};
|
|
29
34
|
export type StringLiteral = BaseNode & {
|
|
30
35
|
type: "StringLiteral";
|
|
31
36
|
raw: string;
|
|
@@ -390,7 +395,7 @@ export type ArrowFunctionExpression = BaseNode & {
|
|
|
390
395
|
params: Array<AssignmentPattern | ArrayPattern | Identifier | ObjectPattern | RestElement>;
|
|
391
396
|
};
|
|
392
397
|
export type FunctionNode = ArrowFunctionExpression | FunctionDeclaration | FunctionExpression;
|
|
393
|
-
export type Expression = ArrowFunctionExpression | AssignmentExpression | ArrayExpression | AwaitExpression | BinaryExpression | BooleanLiteral | CallExpression | ConditionalExpression | ClassExpression | FunctionExpression | Identifier | LogicalExpression | MemberExpression | MetaProperty | NewExpression | NewTargetExpression | NullLiteral | NumericLiteral | ObjectExpression | RegexLiteral | SequenceExpression | StringLiteral | SuperExpression | TaggedTemplateExpression | TemplateLiteral | ThisExpression | UnaryExpression | UpdateExpression | UndefinedLiteral | YieldExpression;
|
|
398
|
+
export type Expression = ArrowFunctionExpression | AssignmentExpression | ArrayExpression | AwaitExpression | BinaryExpression | BooleanLiteral | CallExpression | ConditionalExpression | ClassExpression | FunctionExpression | Identifier | LogicalExpression | MemberExpression | MetaProperty | NewExpression | NewTargetExpression | NullLiteral | NumericLiteral | BigIntLiteral | ObjectExpression | RegexLiteral | SequenceExpression | StringLiteral | SuperExpression | TaggedTemplateExpression | TemplateLiteral | ThisExpression | UnaryExpression | UpdateExpression | UndefinedLiteral | YieldExpression;
|
|
394
399
|
export type ParseResult = Expression | Statement;
|
|
395
400
|
export declare function parse(source: string, filename?: string, owner?: CompileOwner): ParseResult;
|
|
396
401
|
export declare function parseModule(source: string, filename?: string, owner?: CompileOwner): Module;
|
|
@@ -3082,6 +3082,7 @@ function findImportMetaAssignmentInNode(node) {
|
|
|
3082
3082
|
case "BooleanLiteral":
|
|
3083
3083
|
case "NullLiteral":
|
|
3084
3084
|
case "NumericLiteral":
|
|
3085
|
+
case "BigIntLiteral":
|
|
3085
3086
|
case "StringLiteral":
|
|
3086
3087
|
case "ThisExpression":
|
|
3087
3088
|
case "RegexLiteral":
|
|
@@ -3159,6 +3160,13 @@ function isYieldArgumentTerminator(value) {
|
|
|
3159
3160
|
return value === ";" || value === "}" || value === ")" || value === "]" || value === ",";
|
|
3160
3161
|
}
|
|
3161
3162
|
function createNumericLiteral(token) {
|
|
3163
|
+
if (token.value.endsWith("n"))
|
|
3164
|
+
return {
|
|
3165
|
+
type: "BigIntLiteral",
|
|
3166
|
+
raw: token.value,
|
|
3167
|
+
value: token.value.slice(0, -1).replaceAll("_", ""),
|
|
3168
|
+
span: createTokenSpan(token)
|
|
3169
|
+
};
|
|
3162
3170
|
return {
|
|
3163
3171
|
type: "NumericLiteral",
|
|
3164
3172
|
raw: token.value,
|
|
@@ -480,7 +480,8 @@ class Lexer {
|
|
|
480
480
|
this.advance();
|
|
481
481
|
this.advance();
|
|
482
482
|
this.consumeDigitsForBase(isHexDigit, "hexadecimal");
|
|
483
|
-
this.
|
|
483
|
+
if (this.currentChar() === "n")
|
|
484
|
+
this.advance();
|
|
484
485
|
this.rejectInvalidNumericLiteralContinuation();
|
|
485
486
|
return this.source.slice(start.offset, this.index);
|
|
486
487
|
}
|
|
@@ -488,7 +489,8 @@ class Lexer {
|
|
|
488
489
|
this.advance();
|
|
489
490
|
this.advance();
|
|
490
491
|
this.consumeDigitsForBase(isBinaryDigit, "binary");
|
|
491
|
-
this.
|
|
492
|
+
if (this.currentChar() === "n")
|
|
493
|
+
this.advance();
|
|
492
494
|
this.rejectInvalidNumericLiteralContinuation();
|
|
493
495
|
return this.source.slice(start.offset, this.index);
|
|
494
496
|
}
|
|
@@ -496,7 +498,8 @@ class Lexer {
|
|
|
496
498
|
this.advance();
|
|
497
499
|
this.advance();
|
|
498
500
|
this.consumeDigitsForBase(isOctalDigit, "octal");
|
|
499
|
-
this.
|
|
501
|
+
if (this.currentChar() === "n")
|
|
502
|
+
this.advance();
|
|
500
503
|
this.rejectInvalidNumericLiteralContinuation();
|
|
501
504
|
return this.source.slice(start.offset, this.index);
|
|
502
505
|
}
|
|
@@ -512,6 +515,11 @@ class Lexer {
|
|
|
512
515
|
}
|
|
513
516
|
}
|
|
514
517
|
this.consumeDecimalDigits();
|
|
518
|
+
if (this.currentChar() === "n") {
|
|
519
|
+
this.advance();
|
|
520
|
+
this.rejectInvalidNumericLiteralContinuation();
|
|
521
|
+
return this.source.slice(start.offset, this.index);
|
|
522
|
+
}
|
|
515
523
|
if (this.currentChar() === "." && (this.peekChar(1) !== "." || this.peekChar(2) !== ".")) {
|
|
516
524
|
this.advance();
|
|
517
525
|
this.consumeOptionalDecimalDigits();
|
|
@@ -610,7 +618,7 @@ class Lexer {
|
|
|
610
618
|
}
|
|
611
619
|
rejectBigIntSuffix() {
|
|
612
620
|
if (this.currentChar() === "n") {
|
|
613
|
-
this.syntaxError("BigInt
|
|
621
|
+
this.syntaxError("BigInt literals cannot contain a fraction or exponent", this.position());
|
|
614
622
|
}
|
|
615
623
|
}
|
|
616
624
|
rejectInvalidNumericLiteralContinuation() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ParseResult as ParsedNode } from "./parse/parser.js";
|
|
2
2
|
export { DisallowedSyntaxError } from "./parse/parser.js";
|
|
3
3
|
export declare const parse: (source: string, filename?: string) => ParsedNode;
|
|
4
|
-
export type { ArrayPattern, ArrayExpression, ArrowFunctionExpression, AssignmentExpression, AssignmentPattern, AssignmentProperty, AwaitExpression, BinaryExpression, BlockStatement, BooleanLiteral, BreakStatement, CallExpression, CatchClause, ClassBody, ClassDeclaration, ClassElement, ClassExpression, ClassNode, ConditionalExpression, ContinueStatement, DoWhileStatement, EmptyStatement, Expression, ExpressionStatement, ExportDefaultDeclaration, ExportNamedDeclaration, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ForInStatement, ForOfStatement, ForStatement, FunctionDeclaration, FunctionExpression, Identifier, IfStatement, LogicalExpression, MemberExpression, MetaProperty, NewExpression, NewTargetExpression, NullLiteral, NumericLiteral, ObjectExpression, ObjectPattern, ParseResult, PatternTarget, Property, RegexLiteral, RestElement, ReturnStatement, SequenceExpression, SourceSpan, SpreadElement, Statement, StringLiteral, SuperExpression, SwitchCase, SwitchStatement, TaggedTemplateExpression, TemplateElement, TemplateLiteral, ThisExpression, ThrowStatement, TryStatement, UnaryExpression, UndefinedLiteral, UpdateExpression, UpdateTarget, VariableDeclaration, VariableDeclarationKind, VariableDeclarator, WhileStatement } from "./parse/parser.js";
|
|
4
|
+
export type { ArrayPattern, ArrayExpression, ArrowFunctionExpression, AssignmentExpression, AssignmentPattern, AssignmentProperty, AwaitExpression, BinaryExpression, BigIntLiteral, BlockStatement, BooleanLiteral, BreakStatement, CallExpression, CatchClause, ClassBody, ClassDeclaration, ClassElement, ClassExpression, ClassNode, ConditionalExpression, ContinueStatement, DoWhileStatement, EmptyStatement, Expression, ExpressionStatement, ExportDefaultDeclaration, ExportNamedDeclaration, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ForInStatement, ForOfStatement, ForStatement, FunctionDeclaration, FunctionExpression, Identifier, IfStatement, LogicalExpression, MemberExpression, MetaProperty, NewExpression, NewTargetExpression, NullLiteral, NumericLiteral, ObjectExpression, ObjectPattern, ParseResult, PatternTarget, Property, RegexLiteral, RestElement, ReturnStatement, SequenceExpression, SourceSpan, SpreadElement, Statement, StringLiteral, SuperExpression, SwitchCase, SwitchStatement, TaggedTemplateExpression, TemplateElement, TemplateLiteral, ThisExpression, ThrowStatement, TryStatement, UnaryExpression, UndefinedLiteral, UpdateExpression, UpdateTarget, VariableDeclaration, VariableDeclarationKind, VariableDeclarator, WhileStatement } from "./parse/parser.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validateBigIntData(value: unknown): asserts value is string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function validateBigIntData(value) {
|
|
2
|
+
if (typeof value !== "string" || value.length === 0)
|
|
3
|
+
throw new TypeError("Invalid BigInt snapshot value.");
|
|
4
|
+
if (value === "0")
|
|
5
|
+
return;
|
|
6
|
+
const start = value[0] === "-" ? 1 : 0;
|
|
7
|
+
if (start === value.length || value[start] === "0")
|
|
8
|
+
throw new TypeError("Invalid BigInt snapshot value.");
|
|
9
|
+
for (let index = start; index < value.length; index++) {
|
|
10
|
+
const code = value.charCodeAt(index);
|
|
11
|
+
if (code < 48 || code > 57)
|
|
12
|
+
throw new TypeError("Invalid BigInt snapshot value.");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -4,7 +4,7 @@ import { isSandboxRegExpIterator, regexpIteratorState } from "../interp/regexp-i
|
|
|
4
4
|
import { hasCustomRegexProperties, serializeRegexProperties } from "./regexp-properties.js";
|
|
5
5
|
export const EXECUTION_SEMANTICS = "jobs-v8";
|
|
6
6
|
import { assertSnapshotGraphDepth } from "../graph-depth.js";
|
|
7
|
-
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
7
|
+
import { hasGuestObjectState, hasNullObjectPrototype } from "../interp/object-model.js";
|
|
8
8
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
9
9
|
import { getSandboxArgumentEntries, isSandboxArguments } from "../interp/arguments.js";
|
|
10
10
|
import { serializeArguments } from "./arguments.js";
|
|
@@ -58,6 +58,8 @@ function createDumpFile(snapshot) {
|
|
|
58
58
|
return dumped;
|
|
59
59
|
}
|
|
60
60
|
function serializeDumpValue(value, path, state) {
|
|
61
|
+
if (typeof value === "bigint")
|
|
62
|
+
return { kind: "bigint", value: String(value) };
|
|
61
63
|
if (typeof value === "symbol")
|
|
62
64
|
return serializeSymbol(value, state.heapIds, state.heap);
|
|
63
65
|
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
@@ -110,10 +112,16 @@ function serializeHeapReference(value, path, state) {
|
|
|
110
112
|
if (isSandboxRegExpIterator(value)) {
|
|
111
113
|
const snapshot = regexpIteratorState(value);
|
|
112
114
|
const matcher = snapshot.matcher;
|
|
115
|
+
const serializedMatcher = snapshot.global === undefined && isSandboxRegex(matcher)
|
|
116
|
+
? { kind: "regex", source: matcher.source, flags: matcher.flags, lastIndex: Number(matcher.lastIndex) }
|
|
117
|
+
: serializeDumpValue(matcher, `${path}.<matcher>`, state);
|
|
118
|
+
if (serializedMatcher === SKIP_VALUE)
|
|
119
|
+
throw new TypeError("Unsupported RegExp iterator matcher in public dump.");
|
|
113
120
|
const entries = Object.create(null);
|
|
114
121
|
state.heap[String(id)] = {
|
|
115
122
|
kind: "regexp-iterator", exhausted: snapshot.exhausted,
|
|
116
|
-
matcher:
|
|
123
|
+
matcher: serializedMatcher,
|
|
124
|
+
...(snapshot.global === undefined ? {} : { global: snapshot.global, unicode: snapshot.unicode }),
|
|
117
125
|
input: snapshot.input ?? { kind: "undefined" }, entries,
|
|
118
126
|
symbolEntries: serializeSymbolProperties(value, entry => {
|
|
119
127
|
const serialized = serializeDumpValue(entry, `${path}.[symbol]`, state);
|
|
@@ -192,6 +200,7 @@ function serializeHeapReference(value, path, state) {
|
|
|
192
200
|
});
|
|
193
201
|
state.heap[String(id)] = {
|
|
194
202
|
kind: "object",
|
|
203
|
+
...(hasNullObjectPrototype(value) ? { sandboxNullPrototype: true } : {}),
|
|
195
204
|
entries: serializeObjectEntries(value, path, state),
|
|
196
205
|
...(symbolEntries.length === 0 ? {} : { symbolEntries }),
|
|
197
206
|
...(errorType === undefined ? {} : { errorType })
|
|
@@ -227,6 +236,7 @@ function indexHeapContainers(snapshot) {
|
|
|
227
236
|
for (const [value, stat] of stats.entries()) {
|
|
228
237
|
if (stat.count > 1 ||
|
|
229
238
|
stat.cyclic ||
|
|
239
|
+
hasNullObjectPrototype(value) ||
|
|
230
240
|
ownSerializableSymbolKeys(value).length > 0 ||
|
|
231
241
|
isSandboxBox(value) ||
|
|
232
242
|
isSandboxRegExpIterator(value) ||
|
|
@@ -8,6 +8,9 @@ import { type SandboxClosure, type SandboxPromise, type SandboxValue } from "../
|
|
|
8
8
|
import { type SerializedArguments } from "./arguments.js";
|
|
9
9
|
type Atom = boolean | null | number | string | {
|
|
10
10
|
tag: "undefined";
|
|
11
|
+
} | {
|
|
12
|
+
tag: "bigint";
|
|
13
|
+
value: string;
|
|
11
14
|
} | {
|
|
12
15
|
tag: "number";
|
|
13
16
|
value: "NaN" | "Infinity" | "-Infinity" | "-0";
|
|
@@ -32,6 +35,8 @@ type DataNode = {
|
|
|
32
35
|
matcher: Atom;
|
|
33
36
|
input: Atom;
|
|
34
37
|
exhausted: boolean;
|
|
38
|
+
global?: boolean;
|
|
39
|
+
unicode?: boolean;
|
|
35
40
|
properties: Properties;
|
|
36
41
|
extensible: boolean;
|
|
37
42
|
symbolEntries?: Array<SerializedSymbolProperty<Atom>>;
|
|
@@ -69,6 +74,7 @@ type DataNode = {
|
|
|
69
74
|
symbolProperties?: Array<SerializedSymbolProperty<Atom>>;
|
|
70
75
|
extensible: boolean;
|
|
71
76
|
nullPrototype: boolean;
|
|
77
|
+
sandboxNullPrototype?: true;
|
|
72
78
|
errorType?: SandboxErrorName;
|
|
73
79
|
} | {
|
|
74
80
|
kind: "arguments";
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { MAX_DATA_DEPTH } from "../graph-depth.js";
|
|
2
|
+
import { validateBigIntData } from "./bigint.js";
|
|
2
3
|
import { serializeRegexProperties, restoreRegexProperties } from "./regexp-properties.js";
|
|
3
4
|
import { wellKnownSymbols } from "../interp/symbols.js";
|
|
4
5
|
import { symbolData, serializeSymbolProperties } from "./symbols.js";
|
|
5
6
|
import { isSandboxCollectionIterator, restoreSandboxCollectionIterator, snapshotCollectionIterator } from "../interp/collection-iterator.js";
|
|
6
7
|
import { isSandboxRegExpIterator, regexpIteratorState, restoreSandboxRegExpIterator } from "../interp/regexp-iterator.js";
|
|
7
|
-
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
8
|
+
import { hasGuestObjectState, hasNullObjectPrototype, setSandboxPrototype } from "../interp/object-model.js";
|
|
8
9
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
9
10
|
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
10
11
|
import { decodeFloat32Storage, encodeFloat32Storage } from "./float32array.js";
|
|
@@ -29,6 +30,8 @@ export function encodeReplayData(value, options = {}) {
|
|
|
29
30
|
return entry;
|
|
30
31
|
if (entry === undefined)
|
|
31
32
|
return { tag: "undefined" };
|
|
33
|
+
if (typeof entry === "bigint")
|
|
34
|
+
return { tag: "bigint", value: String(entry) };
|
|
32
35
|
if (typeof entry === "symbol") {
|
|
33
36
|
let id = symbols.get(entry);
|
|
34
37
|
if (id === undefined) {
|
|
@@ -134,7 +137,8 @@ export function encodeReplayData(value, options = {}) {
|
|
|
134
137
|
}
|
|
135
138
|
let symbolIndex = 0;
|
|
136
139
|
const symbolEntries = serializeSymbolProperties(entry, value => encode(value, depth + 1, [...path, { symbol: Math.floor(symbolIndex++ / 2) }]));
|
|
137
|
-
nodes[id] = { kind: "regexp-iterator", matcher: child(snapshot.matcher, "<matcher>"), input: child(snapshot.input, "<input>"), exhausted: snapshot.exhausted, properties, extensible: Object.isExtensible(entry), symbolEntries
|
|
140
|
+
nodes[id] = { kind: "regexp-iterator", matcher: child(snapshot.matcher, "<matcher>"), input: child(snapshot.input, "<input>"), exhausted: snapshot.exhausted, properties, extensible: Object.isExtensible(entry), symbolEntries,
|
|
141
|
+
...(snapshot.global === undefined ? {} : { global: snapshot.global, unicode: snapshot.unicode }) };
|
|
138
142
|
}
|
|
139
143
|
else if (isSandboxCollectionIterator(entry)) {
|
|
140
144
|
const snapshot = snapshotCollectionIterator(entry);
|
|
@@ -195,6 +199,7 @@ export function encodeReplayData(value, options = {}) {
|
|
|
195
199
|
nodes[id] = {
|
|
196
200
|
kind: Array.isArray(entry) ? "array" : "object",
|
|
197
201
|
nullPrototype: prototype === null,
|
|
202
|
+
...(hasNullObjectPrototype(entry) ? { sandboxNullPrototype: true } : {}),
|
|
198
203
|
...(errorType === undefined ? {} : { errorType }),
|
|
199
204
|
extensible: Object.isExtensible(entry),
|
|
200
205
|
properties,
|
|
@@ -241,6 +246,11 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
241
246
|
}
|
|
242
247
|
if (own(atom, "tag") === "undefined")
|
|
243
248
|
return undefined;
|
|
249
|
+
if (own(atom, "tag") === "bigint") {
|
|
250
|
+
const value = own(atom, "value");
|
|
251
|
+
validateBigIntData(value);
|
|
252
|
+
return BigInt(value);
|
|
253
|
+
}
|
|
244
254
|
if (atom.tag === "number") {
|
|
245
255
|
switch (own(atom, "value")) {
|
|
246
256
|
case "NaN":
|
|
@@ -326,7 +336,7 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
326
336
|
own(record(nodes[Number(payloadRecord.id)]), "kind") === "symbol";
|
|
327
337
|
if (typeof payload !== "number" && typeof payload !== "string" && typeof payload !== "boolean" &&
|
|
328
338
|
!symbolReference &&
|
|
329
|
-
(payload === null || typeof payload !== "object" || own(record(payload), "tag")
|
|
339
|
+
(payload === null || typeof payload !== "object" || !["number", "bigint"].includes(String(own(record(payload), "tag")))))
|
|
330
340
|
throw new TypeError("Invalid boxed primitive payload.");
|
|
331
341
|
const result = createSandboxBox(child(payload));
|
|
332
342
|
restored.set(id, result);
|
|
@@ -365,11 +375,14 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
365
375
|
restored.set(id, result);
|
|
366
376
|
const matcher = child(own(node, "matcher"));
|
|
367
377
|
const input = child(own(node, "input"));
|
|
368
|
-
if (
|
|
378
|
+
if ((node.global !== undefined || node.unicode !== undefined) && (typeof node.global !== "boolean" || typeof node.unicode !== "boolean"))
|
|
379
|
+
throw new TypeError("Invalid replay RegExp iterator modes.");
|
|
380
|
+
if (matcher !== undefined && (node.global === undefined ? !isSandboxRegex(matcher) : matcher === null || typeof matcher !== "object"))
|
|
369
381
|
throw new TypeError("Invalid replay RegExp iterator matcher.");
|
|
370
382
|
if (input !== undefined && typeof input !== "string")
|
|
371
383
|
throw new TypeError("Invalid replay RegExp iterator input.");
|
|
372
|
-
restoreSandboxRegExpIterator({ matcher, input, exhausted
|
|
384
|
+
restoreSandboxRegExpIterator({ matcher, input, exhausted,
|
|
385
|
+
...(node.global === undefined ? {} : { global: node.global, unicode: node.unicode }) }, result);
|
|
373
386
|
defineProperties(result, record(own(node, "properties")), child, node.symbolEntries);
|
|
374
387
|
if (!node.extensible)
|
|
375
388
|
Object.preventExtensions(result);
|
|
@@ -450,6 +463,11 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
450
463
|
throw new TypeError("Invalid replay object metadata.");
|
|
451
464
|
}
|
|
452
465
|
const result = kind === "array" ? [] : Object.create(node.nullPrototype ? null : Object.prototype);
|
|
466
|
+
if (Object.hasOwn(node, "sandboxNullPrototype")) {
|
|
467
|
+
if (kind !== "object" || node.sandboxNullPrototype !== true)
|
|
468
|
+
throw new TypeError("Invalid replay object prototype.");
|
|
469
|
+
setSandboxPrototype(result, null);
|
|
470
|
+
}
|
|
453
471
|
if (Object.hasOwn(node, "errorType")) {
|
|
454
472
|
sandboxErrorTypes.set(result, node.errorType);
|
|
455
473
|
}
|
|
@@ -234,6 +234,8 @@ function deserializeValue(value, state) {
|
|
|
234
234
|
if (Array.isArray(value)) {
|
|
235
235
|
return value.map((entry) => deserializeValue(entry, state));
|
|
236
236
|
}
|
|
237
|
+
if (value.kind === "bigint" && typeof value.value === "string")
|
|
238
|
+
return BigInt(value.value);
|
|
237
239
|
if (isSerializedUndefinedValue(value)) {
|
|
238
240
|
return undefined;
|
|
239
241
|
}
|
|
@@ -439,11 +441,12 @@ function restoreHeapValue(id, state) {
|
|
|
439
441
|
state.heapValueById.set(id, iterator);
|
|
440
442
|
const matcher = deserializeValue(serialized.matcher, state);
|
|
441
443
|
const input = deserializeValue(serialized.input, state);
|
|
442
|
-
if (matcher !== undefined && !isSandboxRegex(matcher))
|
|
444
|
+
if (matcher !== undefined && (serialized.global === undefined ? !isSandboxRegex(matcher) : matcher === null || typeof matcher !== "object"))
|
|
443
445
|
throw new TypeError("Invalid RegExp iterator matcher.");
|
|
444
446
|
if (input !== undefined && typeof input !== "string")
|
|
445
447
|
throw new TypeError("Invalid RegExp iterator input.");
|
|
446
|
-
restoreSandboxRegExpIterator({ matcher, input, exhausted: serialized.exhausted
|
|
448
|
+
restoreSandboxRegExpIterator({ matcher: matcher, input, exhausted: serialized.exhausted,
|
|
449
|
+
...(serialized.global === undefined ? {} : { global: serialized.global, unicode: serialized.unicode }) }, iterator);
|
|
447
450
|
for (const [key, entry] of Object.entries(serialized.entries))
|
|
448
451
|
Object.defineProperty(iterator, key, { value: deserializeValue(entry, state), enumerable: true, configurable: true, writable: true });
|
|
449
452
|
restoreSymbolProperties(iterator, serialized.symbolEntries, entry => deserializeValue(entry, state));
|
|
@@ -478,6 +481,11 @@ function restoreHeapValue(id, state) {
|
|
|
478
481
|
}
|
|
479
482
|
const object = Object.create(null);
|
|
480
483
|
state.heapValueById.set(id, object);
|
|
484
|
+
if (Object.hasOwn(serialized, "sandboxNullPrototype")) {
|
|
485
|
+
if (serialized.sandboxNullPrototype !== true)
|
|
486
|
+
throw new TypeError("Invalid object prototype.");
|
|
487
|
+
setSandboxPrototype(object, null);
|
|
488
|
+
}
|
|
481
489
|
if (serialized.errorType !== undefined)
|
|
482
490
|
sandboxErrorTypes.set(object, serialized.errorType);
|
|
483
491
|
for (const [key, entry] of Object.entries(serialized.entries)) {
|
|
@@ -54,6 +54,8 @@ export type SerializedHeapValue = {
|
|
|
54
54
|
matcher: SerializedSnapshotValue;
|
|
55
55
|
input: SerializedSnapshotValue;
|
|
56
56
|
exhausted: boolean;
|
|
57
|
+
global?: boolean;
|
|
58
|
+
unicode?: boolean;
|
|
57
59
|
entries: Record<string, SerializedSnapshotValue>;
|
|
58
60
|
symbolEntries?: Array<SerializedSymbolProperty<SerializedSnapshotValue>>;
|
|
59
61
|
} | SerializedSymbol | BoxedData<SerializedSnapshotValue> | ({
|
|
@@ -73,6 +75,7 @@ export type SerializedHeapValue = {
|
|
|
73
75
|
entries: Record<string, SerializedSnapshotValue>;
|
|
74
76
|
}) | SerializedArguments<SerializedSnapshotValue> | SerializedArray<SerializedSnapshotValue> | {
|
|
75
77
|
kind: "object";
|
|
78
|
+
sandboxNullPrototype?: true;
|
|
76
79
|
entries: Record<string, SerializedSnapshotValue>;
|
|
77
80
|
symbolEntries?: Array<SerializedSymbolProperty<SerializedSnapshotValue>>;
|
|
78
81
|
errorType?: SandboxErrorName;
|
|
@@ -102,7 +105,7 @@ export type RuntimePromiseValue = {
|
|
|
102
105
|
id: SnapshotId;
|
|
103
106
|
promise?: Promise<unknown>;
|
|
104
107
|
};
|
|
105
|
-
export type RuntimeSnapshotValue = symbol | SandboxBox | Date | Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
108
|
+
export type RuntimeSnapshotValue = bigint | symbol | SandboxBox | Date | Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
106
109
|
[key: string]: RuntimeSnapshotValue;
|
|
107
110
|
};
|
|
108
111
|
export type RuntimeScopeFrame = {
|
|
@@ -3,7 +3,7 @@ import { hasCustomRegexProperties, serializeRegexProperties } from "./regexp-pro
|
|
|
3
3
|
import { ownSerializableSymbolKeys, serializeSymbol, serializeSymbolProperties } from "./symbols.js";
|
|
4
4
|
import { collectionIteratorState, isSandboxCollectionIterator, snapshotCollectionIterator } from "../interp/collection-iterator.js";
|
|
5
5
|
import { isSandboxRegExpIterator, regexpIteratorState } from "../interp/regexp-iterator.js";
|
|
6
|
-
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
6
|
+
import { hasGuestObjectState, hasNullObjectPrototype } from "../interp/object-model.js";
|
|
7
7
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
8
8
|
import { assertSnapshotGraphDepth } from "../graph-depth.js";
|
|
9
9
|
import { serializeArguments } from "./arguments.js";
|
|
@@ -116,6 +116,8 @@ function serializeValue(value, path, state) {
|
|
|
116
116
|
: "-Infinity"
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
+
if (typeof value === "bigint")
|
|
120
|
+
return { kind: "bigint", value: String(value) };
|
|
119
121
|
if (Array.isArray(value)) {
|
|
120
122
|
const reference = serializeHeapReference(value, path, state);
|
|
121
123
|
if (reference !== undefined) {
|
|
@@ -220,6 +222,7 @@ function serializeHeapReference(value, path, state) {
|
|
|
220
222
|
const entries = Object.create(null);
|
|
221
223
|
state.heap[String(id)] = {
|
|
222
224
|
kind: "regexp-iterator", matcher: serializeValue(snapshot.matcher, `${path}.<matcher>`, state),
|
|
225
|
+
...(snapshot.global === undefined ? {} : { global: snapshot.global, unicode: snapshot.unicode }),
|
|
223
226
|
input: serializeValue(snapshot.input, `${path}.<input>`, state), exhausted: snapshot.exhausted, entries,
|
|
224
227
|
symbolEntries: serializeSymbolProperties(value, entry => serializeValue(entry, `${path}.[symbol]`, state))
|
|
225
228
|
};
|
|
@@ -283,6 +286,7 @@ function serializeHeapReference(value, path, state) {
|
|
|
283
286
|
const errorType = sandboxErrorTypes.get(value);
|
|
284
287
|
const serializedObject = {
|
|
285
288
|
kind: "object",
|
|
289
|
+
...(hasNullObjectPrototype(value) ? { sandboxNullPrototype: true } : {}),
|
|
286
290
|
entries,
|
|
287
291
|
...(errorType === undefined ? {} : { errorType })
|
|
288
292
|
};
|
|
@@ -359,6 +363,7 @@ function indexHeapContainers(input) {
|
|
|
359
363
|
for (const [value, stat] of stats.entries()) {
|
|
360
364
|
if (stat.count > 1 ||
|
|
361
365
|
stat.cyclic ||
|
|
366
|
+
hasNullObjectPrototype(value) ||
|
|
362
367
|
ownSerializableSymbolKeys(value).length > 0 ||
|
|
363
368
|
(isSandboxRegex(value) && (hasCustomRegexProperties(value) || !Number.isSafeInteger(value.lastIndex) ||
|
|
364
369
|
(typeof value.lastIndex === "number" && value.lastIndex < 0) || Object.is(value.lastIndex, -0))) ||
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { replaceErrorStack, sandboxErrorNames } from "../error/shape.js";
|
|
2
|
+
import { validateBigIntData } from "./bigint.js";
|
|
2
3
|
import { validateRegexProperties } from "./regexp-properties.js";
|
|
3
4
|
import { wellKnownSymbols } from "../interp/symbols.js";
|
|
4
5
|
import { types } from "node:util";
|
|
@@ -115,6 +116,8 @@ function validateDumpHeap(root, state) {
|
|
|
115
116
|
continue;
|
|
116
117
|
}
|
|
117
118
|
if (entry.kind === "object") {
|
|
119
|
+
if (Object.hasOwn(entry, "sandboxNullPrototype") && entry.sandboxNullPrototype !== true)
|
|
120
|
+
fail("invalidValue", `${path}.sandboxNullPrototype`, "invalid object prototype");
|
|
118
121
|
requireRecord(entry.entries, `${path}.entries`);
|
|
119
122
|
continue;
|
|
120
123
|
}
|
|
@@ -355,6 +358,15 @@ function validateValue(value, path, depth, state) {
|
|
|
355
358
|
}
|
|
356
359
|
function validateTaggedValue(record, path, state) {
|
|
357
360
|
switch (record.kind) {
|
|
361
|
+
case "bigint":
|
|
362
|
+
requireString(record.value, `${path}.value`, state.limits);
|
|
363
|
+
try {
|
|
364
|
+
validateBigIntData(record.value);
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
fail("invalidValue", `${path}.value`, "invalid BigInt value");
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
358
370
|
case "undefined":
|
|
359
371
|
return;
|
|
360
372
|
case "number":
|
|
@@ -394,7 +406,11 @@ function validateTaggedValue(record, path, state) {
|
|
|
394
406
|
return;
|
|
395
407
|
case "array":
|
|
396
408
|
case "arguments":
|
|
409
|
+
return;
|
|
397
410
|
case "object":
|
|
411
|
+
if (Object.hasOwn(record, "sandboxNullPrototype") && record.sandboxNullPrototype !== true)
|
|
412
|
+
fail("invalidValue", `${path}.sandboxNullPrototype`, "invalid object prototype");
|
|
413
|
+
return;
|
|
398
414
|
case "map":
|
|
399
415
|
case "set":
|
|
400
416
|
case "collection-iterator":
|
|
@@ -474,6 +490,8 @@ function validateHeapValue(value, path, state, heap) {
|
|
|
474
490
|
if (record.kind === "set")
|
|
475
491
|
requireArray(record.values, `${path}.values`, state);
|
|
476
492
|
if (record.kind === "regexp-iterator") {
|
|
493
|
+
if ((record.global !== undefined || record.unicode !== undefined) && (typeof record.global !== "boolean" || typeof record.unicode !== "boolean"))
|
|
494
|
+
fail("invalidValue", path, "invalid RegExp iterator modes");
|
|
477
495
|
if (typeof record.exhausted !== "boolean")
|
|
478
496
|
fail("invalidValue", `${path}.exhausted`, "invalid iterator exhaustion");
|
|
479
497
|
if (!Object.hasOwn(record, "matcher") || !Object.hasOwn(record, "input"))
|
|
@@ -539,6 +557,15 @@ function validateBoxedRecord(record, path, heap) {
|
|
|
539
557
|
if (typeof value === "number" || typeof value === "string" || typeof value === "boolean")
|
|
540
558
|
return;
|
|
541
559
|
const number = requireRecord(value, `${path}.value`);
|
|
560
|
+
if (number.kind === "bigint") {
|
|
561
|
+
try {
|
|
562
|
+
validateBigIntData(number.value);
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
fail("invalidValue", `${path}.value`, "invalid boxed BigInt payload");
|
|
566
|
+
}
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
542
569
|
if (number.kind === "ref") {
|
|
543
570
|
const id = requireSafeInteger(number.id, `${path}.value.id`, 1);
|
|
544
571
|
const target = requireRecord(heap[String(id)], `${path}.value`);
|