poe-code 14.0.72 → 14.0.74
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 +2674 -1760
- 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-VYUHL33E.js → chunk-2J6W3YGB.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-6UY4Z7WY.js → chunk-YEZOXLY4.js} +6279 -5426
- package/packages/safe-js/dist/chunks/chunk-YEZOXLY4.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 +10 -0
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/interp/cancel.js +3 -0
- package/packages/safe-js/dist/interp/globals/misc.js +2 -1
- package/packages/safe-js/dist/interp/globals/object-array.js +9 -7
- package/packages/safe-js/dist/interp/globals/object.js +5 -2
- package/packages/safe-js/dist/interp/globals/regex.js +88 -7
- package/packages/safe-js/dist/interp/interpreter.js +21 -14
- package/packages/safe-js/dist/interp/iteration.js +6 -1
- package/packages/safe-js/dist/interp/methods/regex.d.ts +7 -3
- package/packages/safe-js/dist/interp/methods/regex.js +132 -23
- package/packages/safe-js/dist/interp/methods/regexp-iterator.d.ts +8 -0
- package/packages/safe-js/dist/interp/methods/regexp-iterator.js +49 -0
- package/packages/safe-js/dist/interp/methods/string.d.ts +2 -0
- package/packages/safe-js/dist/interp/methods/string.js +460 -127
- package/packages/safe-js/dist/interp/object-model.d.ts +2 -0
- package/packages/safe-js/dist/interp/object-model.js +45 -12
- package/packages/safe-js/dist/interp/regexp-iterator.d.ts +14 -0
- package/packages/safe-js/dist/interp/regexp-iterator.js +18 -0
- package/packages/safe-js/dist/interp/regexp-properties.d.ts +3 -0
- package/packages/safe-js/dist/interp/regexp-properties.js +7 -0
- package/packages/safe-js/dist/interp/string-coercion.js +11 -7
- package/packages/safe-js/dist/interp/values.d.ts +3 -1
- package/packages/safe-js/dist/interp/values.js +111 -2
- package/packages/safe-js/dist/snapshot/dump-format.js +51 -9
- package/packages/safe-js/dist/snapshot/regexp-properties.d.ts +18 -0
- package/packages/safe-js/dist/snapshot/regexp-properties.js +58 -0
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +12 -3
- package/packages/safe-js/dist/snapshot/replay-data.js +35 -1
- package/packages/safe-js/dist/snapshot/replay-inputs.js +17 -0
- package/packages/safe-js/dist/snapshot/restore.js +19 -1
- package/packages/safe-js/dist/snapshot/serialize.d.ts +12 -3
- package/packages/safe-js/dist/snapshot/serialize.js +40 -17
- package/packages/safe-js/dist/snapshot/validation.js +25 -2
- package/packages/safe-js/dist/chunks/chunk-6UY4Z7WY.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-VYUHL33E.js.map → chunk-2J6W3YGB.js.map} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RegexPropertyData } from "./regexp-properties.js";
|
|
1
2
|
import { type SerializedSymbol, type SerializedSymbolProperty } from "./symbols.js";
|
|
2
3
|
import { type CollectionIterationMethod } from "../interp/collection-iterator.js";
|
|
3
4
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
@@ -26,7 +27,15 @@ type Properties = Record<string, {
|
|
|
26
27
|
enumerable: boolean;
|
|
27
28
|
writable: boolean;
|
|
28
29
|
}>;
|
|
29
|
-
type DataNode =
|
|
30
|
+
type DataNode = {
|
|
31
|
+
kind: "regexp-iterator";
|
|
32
|
+
matcher: Atom;
|
|
33
|
+
input: Atom;
|
|
34
|
+
exhausted: boolean;
|
|
35
|
+
properties: Properties;
|
|
36
|
+
extensible: boolean;
|
|
37
|
+
symbolEntries?: Array<SerializedSymbolProperty<Atom>>;
|
|
38
|
+
} | SerializedSymbol | {
|
|
30
39
|
kind: "boxed";
|
|
31
40
|
value: Atom;
|
|
32
41
|
properties: Properties;
|
|
@@ -70,12 +79,12 @@ type DataNode = SerializedSymbol | {
|
|
|
70
79
|
} | {
|
|
71
80
|
kind: "set";
|
|
72
81
|
values: Atom[];
|
|
73
|
-
} | {
|
|
82
|
+
} | ({
|
|
74
83
|
kind: "regex";
|
|
75
84
|
source: string;
|
|
76
85
|
flags: string;
|
|
77
86
|
lastIndex: Atom;
|
|
78
|
-
};
|
|
87
|
+
} & RegexPropertyData<Atom>);
|
|
79
88
|
export type ReplayData = {
|
|
80
89
|
root: Atom;
|
|
81
90
|
nodes: DataNode[];
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { MAX_DATA_DEPTH } from "../graph-depth.js";
|
|
2
|
+
import { serializeRegexProperties, restoreRegexProperties } from "./regexp-properties.js";
|
|
2
3
|
import { wellKnownSymbols } from "../interp/symbols.js";
|
|
3
4
|
import { symbolData, serializeSymbolProperties } from "./symbols.js";
|
|
4
5
|
import { isSandboxCollectionIterator, restoreSandboxCollectionIterator, snapshotCollectionIterator } from "../interp/collection-iterator.js";
|
|
6
|
+
import { isSandboxRegExpIterator, regexpIteratorState, restoreSandboxRegExpIterator } from "../interp/regexp-iterator.js";
|
|
5
7
|
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
6
8
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
7
9
|
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
@@ -122,6 +124,18 @@ export function encodeReplayData(value, options = {}) {
|
|
|
122
124
|
}
|
|
123
125
|
nodes[id] = { ...storage, properties, extensible: Object.isExtensible(entry) };
|
|
124
126
|
}
|
|
127
|
+
else if (isSandboxRegExpIterator(entry)) {
|
|
128
|
+
const snapshot = regexpIteratorState(entry);
|
|
129
|
+
const properties = Object.create(null);
|
|
130
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(entry))) {
|
|
131
|
+
if (!("value" in descriptor))
|
|
132
|
+
throw new TypeError(`Cannot record replay data accessor '${key}'.`);
|
|
133
|
+
properties[key] = { value: child(descriptor.value, JSON.stringify(["property", key])), configurable: descriptor.configurable === true, enumerable: descriptor.enumerable === true, writable: descriptor.writable === true };
|
|
134
|
+
}
|
|
135
|
+
let symbolIndex = 0;
|
|
136
|
+
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 };
|
|
138
|
+
}
|
|
125
139
|
else if (isSandboxCollectionIterator(entry)) {
|
|
126
140
|
const snapshot = snapshotCollectionIterator(entry);
|
|
127
141
|
const properties = Object.create(null);
|
|
@@ -152,7 +166,8 @@ export function encodeReplayData(value, options = {}) {
|
|
|
152
166
|
kind: "regex",
|
|
153
167
|
source: entry.source,
|
|
154
168
|
flags: entry.flags,
|
|
155
|
-
lastIndex: child(entry.lastIndex, "lastIndex")
|
|
169
|
+
lastIndex: child(entry.lastIndex, "lastIndex"),
|
|
170
|
+
...serializeRegexProperties(entry, value => child(value, "<regex-property>"))
|
|
156
171
|
};
|
|
157
172
|
}
|
|
158
173
|
else if (isSandboxArguments(entry)) {
|
|
@@ -342,6 +357,24 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
342
357
|
Object.preventExtensions(result);
|
|
343
358
|
return result;
|
|
344
359
|
}
|
|
360
|
+
if (kind === "regexp-iterator") {
|
|
361
|
+
const exhausted = own(node, "exhausted");
|
|
362
|
+
if (typeof exhausted !== "boolean" || typeof node.extensible !== "boolean")
|
|
363
|
+
throw new TypeError("Invalid replay RegExp iterator.");
|
|
364
|
+
const result = restoreSandboxRegExpIterator({ matcher: undefined, input: undefined, exhausted: true });
|
|
365
|
+
restored.set(id, result);
|
|
366
|
+
const matcher = child(own(node, "matcher"));
|
|
367
|
+
const input = child(own(node, "input"));
|
|
368
|
+
if (matcher !== undefined && !isSandboxRegex(matcher))
|
|
369
|
+
throw new TypeError("Invalid replay RegExp iterator matcher.");
|
|
370
|
+
if (input !== undefined && typeof input !== "string")
|
|
371
|
+
throw new TypeError("Invalid replay RegExp iterator input.");
|
|
372
|
+
restoreSandboxRegExpIterator({ matcher, input, exhausted }, result);
|
|
373
|
+
defineProperties(result, record(own(node, "properties")), child, node.symbolEntries);
|
|
374
|
+
if (!node.extensible)
|
|
375
|
+
Object.preventExtensions(result);
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
345
378
|
if (kind === "collection-iterator") {
|
|
346
379
|
const collectionKind = own(node, "collectionKind");
|
|
347
380
|
const method = own(node, "method");
|
|
@@ -387,6 +420,7 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
387
420
|
const result = createSandboxRegex(node.source, node.flags, 0, compilation);
|
|
388
421
|
restored.set(id, result);
|
|
389
422
|
result.lastIndex = child(own(node, "lastIndex"));
|
|
423
|
+
restoreRegexProperties(result, node, child);
|
|
390
424
|
return result;
|
|
391
425
|
}
|
|
392
426
|
if (kind === "arguments") {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { collectionIteratorState, isSandboxCollectionIterator } from "../interp/collection-iterator.js";
|
|
2
|
+
import { regexpIteratorState, isSandboxRegExpIterator } from "../interp/regexp-iterator.js";
|
|
2
3
|
import { createSandboxPromise, isSandboxClosure, isSandboxMap, isSandboxSet, isSandboxPromise } from "../interp/values.js";
|
|
3
4
|
import { decodeReplayData, encodeReplayData } from "./replay-data.js";
|
|
4
5
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
@@ -59,6 +60,20 @@ export function prepareReplayInputs(current, saved, preparePromise, onCapability
|
|
|
59
60
|
value = descriptor.value;
|
|
60
61
|
continue;
|
|
61
62
|
}
|
|
63
|
+
if (isSandboxRegExpIterator(value)) {
|
|
64
|
+
if (key === "<matcher>")
|
|
65
|
+
value = regexpIteratorState(value).matcher;
|
|
66
|
+
else if (key === "<input>")
|
|
67
|
+
value = regexpIteratorState(value).input;
|
|
68
|
+
else {
|
|
69
|
+
const property = JSON.parse(key);
|
|
70
|
+
if (!Array.isArray(property) || property.length !== 2 || property[0] !== "property" || typeof property[1] !== "string")
|
|
71
|
+
throw new TypeError("Invalid replay input iterator capability path.");
|
|
72
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, property[1]);
|
|
73
|
+
value = descriptor !== undefined && "value" in descriptor ? descriptor.value : undefined;
|
|
74
|
+
}
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
62
77
|
if (isSandboxCollectionIterator(value)) {
|
|
63
78
|
if (key === "<collection>")
|
|
64
79
|
value = collectionIteratorState(value).collection;
|
|
@@ -135,6 +150,7 @@ function assertReplayInputShape(restored) {
|
|
|
135
150
|
isSandboxClosure(restored) ||
|
|
136
151
|
isSandboxPromise(restored) ||
|
|
137
152
|
isSandboxCollectionIterator(restored) ||
|
|
153
|
+
isSandboxRegExpIterator(restored) ||
|
|
138
154
|
isSandboxMap(restored) ||
|
|
139
155
|
isSandboxSet(restored))
|
|
140
156
|
throw new TypeError("Invalid replay inputs.");
|
|
@@ -146,6 +162,7 @@ function assertReplayInputShape(restored) {
|
|
|
146
162
|
isSandboxClosure(values[key]) ||
|
|
147
163
|
isSandboxPromise(values[key]) ||
|
|
148
164
|
isSandboxCollectionIterator(values[key]) ||
|
|
165
|
+
isSandboxRegExpIterator(values[key]) ||
|
|
149
166
|
isSandboxMap(values[key]) ||
|
|
150
167
|
isSandboxSet(values[key]))
|
|
151
168
|
throw new TypeError(`Invalid replay input ${key}.`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Budget, SandboxError } from "../interp/budget.js";
|
|
2
|
+
import { restoreRegexProperties } from "./regexp-properties.js";
|
|
2
3
|
import { executeAsyncFunction } from "../interp/async.js";
|
|
3
4
|
import { toPropertyKey } from "../interp/property-key.js";
|
|
4
5
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
@@ -13,10 +14,11 @@ import { getGuestFunctionProperties, getGuestFunctionProperty, getSandboxDataPro
|
|
|
13
14
|
import { functionSources } from "../parse/function-source.js";
|
|
14
15
|
import { wrapCallerInjectedBindings } from "../interp/host-bridge.js";
|
|
15
16
|
import { restoreSandboxCollectionIterator } from "../interp/collection-iterator.js";
|
|
17
|
+
import { restoreSandboxRegExpIterator } from "../interp/regexp-iterator.js";
|
|
16
18
|
import { wellKnownSymbols } from "../interp/symbols.js";
|
|
17
19
|
import { restoreSymbolProperties } from "./symbols.js";
|
|
18
20
|
import { restoreDateProperties } from "./date-properties.js";
|
|
19
|
-
import { isSandboxMap, isSandboxSet } from "../interp/values.js";
|
|
21
|
+
import { isSandboxMap, isSandboxSet, isSandboxRegex } from "../interp/values.js";
|
|
20
22
|
import { createSandboxArguments, createSandboxClosure, createSandboxGenerator, createSandboxMap, createSandboxPromise, createSandboxRegex, createSandboxSet, reconcileCompiledValues } from "../interp/values.js";
|
|
21
23
|
import { createGeneratorChannel, restoreGeneratorChannel } from "../interp/generator.js";
|
|
22
24
|
import { hashSource } from "../parse/hash.js";
|
|
@@ -377,6 +379,7 @@ function restoreHeapValue(id, state) {
|
|
|
377
379
|
const value = createSandboxRegex(serialized.source, serialized.flags, 0, state.compilation);
|
|
378
380
|
state.heapValueById.set(id, value);
|
|
379
381
|
value.lastIndex = deserializeValue(serialized.lastIndex, state);
|
|
382
|
+
restoreRegexProperties(value, serialized, entry => deserializeValue(entry, state));
|
|
380
383
|
return value;
|
|
381
384
|
}
|
|
382
385
|
if (serialized.kind === "float32array") {
|
|
@@ -431,6 +434,21 @@ function restoreHeapValue(id, state) {
|
|
|
431
434
|
Object.preventExtensions(args);
|
|
432
435
|
return args;
|
|
433
436
|
}
|
|
437
|
+
if (serialized.kind === "regexp-iterator") {
|
|
438
|
+
const iterator = restoreSandboxRegExpIterator({ matcher: undefined, input: undefined, exhausted: true });
|
|
439
|
+
state.heapValueById.set(id, iterator);
|
|
440
|
+
const matcher = deserializeValue(serialized.matcher, state);
|
|
441
|
+
const input = deserializeValue(serialized.input, state);
|
|
442
|
+
if (matcher !== undefined && !isSandboxRegex(matcher))
|
|
443
|
+
throw new TypeError("Invalid RegExp iterator matcher.");
|
|
444
|
+
if (input !== undefined && typeof input !== "string")
|
|
445
|
+
throw new TypeError("Invalid RegExp iterator input.");
|
|
446
|
+
restoreSandboxRegExpIterator({ matcher, input, exhausted: serialized.exhausted }, iterator);
|
|
447
|
+
for (const [key, entry] of Object.entries(serialized.entries))
|
|
448
|
+
Object.defineProperty(iterator, key, { value: deserializeValue(entry, state), enumerable: true, configurable: true, writable: true });
|
|
449
|
+
restoreSymbolProperties(iterator, serialized.symbolEntries, entry => deserializeValue(entry, state));
|
|
450
|
+
return iterator;
|
|
451
|
+
}
|
|
434
452
|
if (serialized.kind === "collection-iterator") {
|
|
435
453
|
const iterator = restoreSandboxCollectionIterator({ collection: undefined, collectionKind: serialized.collectionKind, method: serialized.method, index: 0, exhausted: true });
|
|
436
454
|
state.heapValueById.set(id, iterator);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { type RegexPropertyData } from "./regexp-properties.js";
|
|
1
2
|
import { type SerializedSymbol, type SerializedSymbolProperty } from "./symbols.js";
|
|
2
3
|
import { type CollectionIterationMethod, type SandboxCollectionIterator } from "../interp/collection-iterator.js";
|
|
4
|
+
import { type SandboxRegExpIterator } from "../interp/regexp-iterator.js";
|
|
3
5
|
import { type SandboxErrorName } from "../error/shape.js";
|
|
4
6
|
import { type SerializedArguments } from "./arguments.js";
|
|
5
7
|
import { type SerializedArray } from "./arrays.js";
|
|
@@ -47,12 +49,19 @@ export type SerializedReferenceValue = {
|
|
|
47
49
|
kind: "ref";
|
|
48
50
|
id: number;
|
|
49
51
|
};
|
|
50
|
-
export type SerializedHeapValue =
|
|
52
|
+
export type SerializedHeapValue = {
|
|
53
|
+
kind: "regexp-iterator";
|
|
54
|
+
matcher: SerializedSnapshotValue;
|
|
55
|
+
input: SerializedSnapshotValue;
|
|
56
|
+
exhausted: boolean;
|
|
57
|
+
entries: Record<string, SerializedSnapshotValue>;
|
|
58
|
+
symbolEntries?: Array<SerializedSymbolProperty<SerializedSnapshotValue>>;
|
|
59
|
+
} | SerializedSymbol | BoxedData<SerializedSnapshotValue> | ({
|
|
51
60
|
kind: "regex-object";
|
|
52
61
|
source: string;
|
|
53
62
|
flags: string;
|
|
54
63
|
lastIndex: SerializedSnapshotValue;
|
|
55
|
-
} | {
|
|
64
|
+
} & RegexPropertyData<SerializedSnapshotValue>) | {
|
|
56
65
|
kind: "collection-iterator";
|
|
57
66
|
collectionKind: "map" | "set";
|
|
58
67
|
method: CollectionIterationMethod;
|
|
@@ -93,7 +102,7 @@ export type RuntimePromiseValue = {
|
|
|
93
102
|
id: SnapshotId;
|
|
94
103
|
promise?: Promise<unknown>;
|
|
95
104
|
};
|
|
96
|
-
export type RuntimeSnapshotValue = symbol | SandboxBox | Date | Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | SandboxCollectionIterator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
105
|
+
export type RuntimeSnapshotValue = symbol | SandboxBox | Date | Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
97
106
|
[key: string]: RuntimeSnapshotValue;
|
|
98
107
|
};
|
|
99
108
|
export type RuntimeScopeFrame = {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { hashSource } from "../parse/hash.js";
|
|
2
|
+
import { hasCustomRegexProperties, serializeRegexProperties } from "./regexp-properties.js";
|
|
2
3
|
import { ownSerializableSymbolKeys, serializeSymbol, serializeSymbolProperties } from "./symbols.js";
|
|
3
4
|
import { collectionIteratorState, isSandboxCollectionIterator, snapshotCollectionIterator } from "../interp/collection-iterator.js";
|
|
5
|
+
import { isSandboxRegExpIterator, regexpIteratorState } from "../interp/regexp-iterator.js";
|
|
4
6
|
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
5
7
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
6
8
|
import { assertSnapshotGraphDepth } from "../graph-depth.js";
|
|
@@ -12,7 +14,7 @@ import { dateDataProperties, isSandboxDate } from "../interp/date.js";
|
|
|
12
14
|
import { serializeDate } from "./date-properties.js";
|
|
13
15
|
import { boxedDataProperties, isSandboxBox } from "../interp/boxed.js";
|
|
14
16
|
import { encodeBoxedData } from "./boxed.js";
|
|
15
|
-
import { isSandboxArguments, isSandboxGenerator, isSandboxMap, isSandboxRegex, isSandboxSet } from "../interp/values.js";
|
|
17
|
+
import { isSandboxArguments, isSandboxGenerator, isSandboxMap, isSandboxRegex, getRegexProperties, isSandboxSet } from "../interp/values.js";
|
|
16
18
|
export class UnsnapshotableValueError extends Error {
|
|
17
19
|
path;
|
|
18
20
|
constructor(path) {
|
|
@@ -179,7 +181,7 @@ function serializeValue(value, path, state) {
|
|
|
179
181
|
throw new TypeError(`Missing regex heap reference at ${path}.`);
|
|
180
182
|
return { kind: "regex", source: value.source, flags: value.flags, lastIndex: value.lastIndex };
|
|
181
183
|
}
|
|
182
|
-
if (isSandboxBox(value) || isSandboxDate(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxCollectionIterator(value) || isFloat32Array(value)) {
|
|
184
|
+
if (isSandboxBox(value) || isSandboxDate(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxRegExpIterator(value) || isSandboxCollectionIterator(value) || isFloat32Array(value)) {
|
|
183
185
|
const reference = serializeHeapReference(value, path, state);
|
|
184
186
|
if (reference === undefined) {
|
|
185
187
|
throw new TypeError(`Cannot serialize collection without a heap reference at ${path}.`);
|
|
@@ -210,7 +212,19 @@ function serializeHeapReference(value, path, state) {
|
|
|
210
212
|
state.serializedHeapIds.add(id);
|
|
211
213
|
if (isSandboxRegex(value)) {
|
|
212
214
|
state.heap[String(id)] = { kind: "regex-object", source: value.source, flags: value.flags,
|
|
213
|
-
lastIndex: serializeValue(value.lastIndex, `${path}.lastIndex`, state)
|
|
215
|
+
lastIndex: serializeValue(value.lastIndex, `${path}.lastIndex`, state),
|
|
216
|
+
...serializeRegexProperties(value, entry => serializeValue(entry, `${path}.<regex-property>`, state)) };
|
|
217
|
+
}
|
|
218
|
+
else if (isSandboxRegExpIterator(value)) {
|
|
219
|
+
const snapshot = regexpIteratorState(value);
|
|
220
|
+
const entries = Object.create(null);
|
|
221
|
+
state.heap[String(id)] = {
|
|
222
|
+
kind: "regexp-iterator", matcher: serializeValue(snapshot.matcher, `${path}.<matcher>`, state),
|
|
223
|
+
input: serializeValue(snapshot.input, `${path}.<input>`, state), exhausted: snapshot.exhausted, entries,
|
|
224
|
+
symbolEntries: serializeSymbolProperties(value, entry => serializeValue(entry, `${path}.[symbol]`, state))
|
|
225
|
+
};
|
|
226
|
+
for (const [key, entry] of Object.entries(value))
|
|
227
|
+
entries[key] = serializeValue(entry, `${path}.${key}`, state);
|
|
214
228
|
}
|
|
215
229
|
else if (isSandboxCollectionIterator(value)) {
|
|
216
230
|
const snapshot = snapshotCollectionIterator(value);
|
|
@@ -346,7 +360,7 @@ function indexHeapContainers(input) {
|
|
|
346
360
|
if (stat.count > 1 ||
|
|
347
361
|
stat.cyclic ||
|
|
348
362
|
ownSerializableSymbolKeys(value).length > 0 ||
|
|
349
|
-
(isSandboxRegex(value) && (!Number.isSafeInteger(value.lastIndex) ||
|
|
363
|
+
(isSandboxRegex(value) && (hasCustomRegexProperties(value) || !Number.isSafeInteger(value.lastIndex) ||
|
|
350
364
|
(typeof value.lastIndex === "number" && value.lastIndex < 0) || Object.is(value.lastIndex, -0))) ||
|
|
351
365
|
isSandboxBox(value) ||
|
|
352
366
|
isSandboxDate(value) ||
|
|
@@ -355,6 +369,7 @@ function indexHeapContainers(input) {
|
|
|
355
369
|
sandboxErrorTypes.has(value) ||
|
|
356
370
|
isSandboxArguments(value) ||
|
|
357
371
|
isSandboxCollectionIterator(value) ||
|
|
372
|
+
isSandboxRegExpIterator(value) ||
|
|
358
373
|
isSandboxMap(value) ||
|
|
359
374
|
isSandboxSet(value)) {
|
|
360
375
|
heapIds.set(value, nextId);
|
|
@@ -377,6 +392,7 @@ function collectContainerStats(value, stats, ancestors) {
|
|
|
377
392
|
!isFloat32Array(value) &&
|
|
378
393
|
!isSandboxMap(value) &&
|
|
379
394
|
!isSandboxCollectionIterator(value) &&
|
|
395
|
+
!isSandboxRegExpIterator(value) &&
|
|
380
396
|
!isSandboxSet(value)) {
|
|
381
397
|
return;
|
|
382
398
|
}
|
|
@@ -399,19 +415,26 @@ function collectContainerStats(value, stats, ancestors) {
|
|
|
399
415
|
}
|
|
400
416
|
stat.expanded = true;
|
|
401
417
|
ancestors.add(value);
|
|
402
|
-
const entries =
|
|
403
|
-
?
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
418
|
+
const entries = isSandboxRegex(value)
|
|
419
|
+
? Reflect.ownKeys(getRegexProperties(value)).flatMap(key => {
|
|
420
|
+
const descriptor = Object.getOwnPropertyDescriptor(getRegexProperties(value), key);
|
|
421
|
+
return "value" in descriptor ? [descriptor.value] : [];
|
|
422
|
+
})
|
|
423
|
+
: isSandboxDate(value)
|
|
424
|
+
? dateDataProperties(value).flatMap(([key, descriptor]) => typeof key === "string" ? [descriptor.value] : [])
|
|
425
|
+
: isSandboxBox(value)
|
|
426
|
+
? boxedDataProperties(value).map(([, descriptor]) => descriptor.value)
|
|
427
|
+
: isSandboxRegExpIterator(value)
|
|
428
|
+
? [regexpIteratorState(value).matcher, regexpIteratorState(value).input, ...Object.values(value)]
|
|
429
|
+
: isSandboxCollectionIterator(value)
|
|
430
|
+
? [collectionIteratorState(value).collection, ...Object.values(value)]
|
|
431
|
+
: isSandboxArguments(value)
|
|
432
|
+
? Object.values(Object.getOwnPropertyDescriptors(value)).flatMap((descriptor) => "value" in descriptor ? [descriptor.value] : [])
|
|
433
|
+
: isSandboxMap(value)
|
|
434
|
+
? [...value.entries].flatMap(([key, entry]) => [key, entry])
|
|
435
|
+
: isSandboxSet(value)
|
|
436
|
+
? [...value.values]
|
|
437
|
+
: Object.values(value);
|
|
415
438
|
for (const entry of entries) {
|
|
416
439
|
collectContainerStats(entry, stats, ancestors);
|
|
417
440
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { replaceErrorStack, sandboxErrorNames } from "../error/shape.js";
|
|
2
|
+
import { validateRegexProperties } from "./regexp-properties.js";
|
|
2
3
|
import { wellKnownSymbols } from "../interp/symbols.js";
|
|
3
4
|
import { types } from "node:util";
|
|
4
5
|
import { DUMP_FORMAT_VERSION } from "./dump-format.js";
|
|
@@ -84,6 +85,14 @@ function validateDumpHeap(root, state) {
|
|
|
84
85
|
const entry = requireRecord(value, path);
|
|
85
86
|
validateErrorType(entry, path);
|
|
86
87
|
validateSymbolEntries(entry, path, state, heap);
|
|
88
|
+
if (entry.kind === "regexp-iterator") {
|
|
89
|
+
validateHeapValue(entry, path, state, heap);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (entry.kind === "regex-object") {
|
|
93
|
+
validateTaggedValue(entry, path, state);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
87
96
|
if (entry.kind === "boxed") {
|
|
88
97
|
validateBoxedRecord(entry, path, heap);
|
|
89
98
|
continue;
|
|
@@ -376,6 +385,12 @@ function validateTaggedValue(record, path, state) {
|
|
|
376
385
|
requireString(record.flags, `${path}.flags`, state.limits);
|
|
377
386
|
if (!Object.hasOwn(record, "lastIndex"))
|
|
378
387
|
fail("invalidValue", `${path}.lastIndex`, "missing regex cursor");
|
|
388
|
+
try {
|
|
389
|
+
validateRegexProperties(record);
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
fail("invalidValue", path, "invalid RegExp property data");
|
|
393
|
+
}
|
|
379
394
|
return;
|
|
380
395
|
case "array":
|
|
381
396
|
case "arguments":
|
|
@@ -383,6 +398,7 @@ function validateTaggedValue(record, path, state) {
|
|
|
383
398
|
case "map":
|
|
384
399
|
case "set":
|
|
385
400
|
case "collection-iterator":
|
|
401
|
+
case "regexp-iterator":
|
|
386
402
|
return;
|
|
387
403
|
}
|
|
388
404
|
}
|
|
@@ -429,7 +445,7 @@ function validateGeneratorShape(record, path, state) {
|
|
|
429
445
|
function validateHeapValue(value, path, state, heap) {
|
|
430
446
|
const record = requireRecord(value, path);
|
|
431
447
|
validateErrorType(record, path);
|
|
432
|
-
if (!["symbol", "arguments", "array", "object", "map", "set", "float32array", "date", "boxed", "collection-iterator", "regex-object"].includes(String(record.kind)))
|
|
448
|
+
if (!["symbol", "arguments", "array", "object", "map", "set", "float32array", "date", "boxed", "collection-iterator", "regexp-iterator", "regex-object"].includes(String(record.kind)))
|
|
433
449
|
fail("unknownTag", `${path}.kind`, "unknown heap tag");
|
|
434
450
|
validateValue(record, path, 1, state);
|
|
435
451
|
if (record.kind === "symbol")
|
|
@@ -457,6 +473,13 @@ function validateHeapValue(value, path, state, heap) {
|
|
|
457
473
|
}
|
|
458
474
|
if (record.kind === "set")
|
|
459
475
|
requireArray(record.values, `${path}.values`, state);
|
|
476
|
+
if (record.kind === "regexp-iterator") {
|
|
477
|
+
if (typeof record.exhausted !== "boolean")
|
|
478
|
+
fail("invalidValue", `${path}.exhausted`, "invalid iterator exhaustion");
|
|
479
|
+
if (!Object.hasOwn(record, "matcher") || !Object.hasOwn(record, "input"))
|
|
480
|
+
fail("invalidValue", path, "missing RegExp iterator state");
|
|
481
|
+
requireRecord(record.entries, `${path}.entries`);
|
|
482
|
+
}
|
|
460
483
|
if (record.kind === "collection-iterator") {
|
|
461
484
|
if (record.collectionKind !== "map" && record.collectionKind !== "set")
|
|
462
485
|
fail("invalidValue", `${path}.collectionKind`, "invalid iterator brand");
|
|
@@ -473,7 +496,7 @@ function validateHeapValue(value, path, state, heap) {
|
|
|
473
496
|
function validateSymbolEntries(record, path, state, heap) {
|
|
474
497
|
if (record.symbolEntries === undefined)
|
|
475
498
|
return;
|
|
476
|
-
if (record.kind !== "object" && record.kind !== "array" && record.kind !== "date" && record.kind !== "boxed")
|
|
499
|
+
if (record.kind !== "object" && record.kind !== "array" && record.kind !== "date" && record.kind !== "boxed" && record.kind !== "regex-object" && record.kind !== "regexp-iterator")
|
|
477
500
|
fail("invalidValue", `${path}.symbolEntries`, "symbol properties are unsupported for this heap kind");
|
|
478
501
|
const entries = requireArray(record.symbolEntries, `${path}.symbolEntries`, state);
|
|
479
502
|
const keys = new Set();
|