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,22 +1,84 @@
|
|
|
1
|
-
import { createSandboxClosure, getSandboxRegexPattern, isSandboxClosure, isSandboxRegex } from "../values.js";
|
|
1
|
+
import { createSandboxClosure, getSandboxRegexPattern, getRegexProperties, isSandboxClosure, isSandboxRegex } from "../values.js";
|
|
2
2
|
import { matchRegex } from "../regex/engine.js";
|
|
3
3
|
import { invokeBuiltinClosure } from "../builtin-call.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getSandboxPropertyDescriptor, getSandboxPrototype, hasExplicitSandboxPrototype } from "../object-model.js";
|
|
5
|
+
import { readPropertyDescriptor } from "../accessors.js";
|
|
6
|
+
import { retainValues } from "../resources.js";
|
|
5
7
|
import { sandboxNumber, sandboxString } from "../string-coercion.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
import { setSandboxProperty } from "../interpreter.js";
|
|
9
|
+
export async function regexSearch(target, input, budget, context) {
|
|
10
|
+
if (target === null || typeof target !== "object")
|
|
11
|
+
throw new TypeError("RegExp search requires an object receiver.");
|
|
12
|
+
let string;
|
|
13
|
+
let previous;
|
|
14
|
+
let result;
|
|
15
|
+
const release = retainValues(budget, () => [target, input, string, previous, result]);
|
|
16
|
+
const read = (value, key) => {
|
|
17
|
+
if (context?.getProperty !== undefined)
|
|
18
|
+
return context.getProperty(value, key);
|
|
19
|
+
const descriptor = getSandboxPropertyDescriptor(value, key, budget);
|
|
20
|
+
return descriptor === undefined ? undefined : readPropertyDescriptor(descriptor, value, context);
|
|
21
|
+
};
|
|
22
|
+
try {
|
|
23
|
+
string = await sandboxString(input, budget, context);
|
|
24
|
+
input = undefined;
|
|
25
|
+
previous = await read(target, "lastIndex");
|
|
26
|
+
if (!Object.is(previous, 0))
|
|
27
|
+
await setSandboxProperty(target, "lastIndex", 0, budget, true, context);
|
|
28
|
+
result = await regexExec(target, string, budget, context);
|
|
29
|
+
if (!Object.is(await read(target, "lastIndex"), previous))
|
|
30
|
+
await setSandboxProperty(target, "lastIndex", previous, budget, true, context);
|
|
31
|
+
return result === null ? -1 : await read(result, "index");
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
release();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const regexMethodNames = new Set(["exec", "test", "toString"]);
|
|
38
|
+
export const regexFlagProperties = {
|
|
8
39
|
hasIndices: "d", global: "g", ignoreCase: "i", multiline: "m",
|
|
9
40
|
dotAll: "s", unicode: "u", unicodeSets: "v", sticky: "y"
|
|
10
41
|
};
|
|
11
42
|
export function isRegexMethodName(property) {
|
|
12
43
|
return typeof property === "string" && regexMethodNames.has(property);
|
|
13
44
|
}
|
|
14
|
-
export function getRegexMember(target, property, budget) {
|
|
45
|
+
export function getRegexMember(target, property, budget, context) {
|
|
15
46
|
if (property === "source")
|
|
16
47
|
return escapeRegexSource(target.source, budget);
|
|
17
48
|
if (property === "flags") {
|
|
18
|
-
|
|
19
|
-
|
|
49
|
+
let flags = "";
|
|
50
|
+
const entries = Object.entries(regexFlagProperties);
|
|
51
|
+
const release = retainValues(budget, () => [target, flags]);
|
|
52
|
+
const read = (index) => {
|
|
53
|
+
if (index === entries.length)
|
|
54
|
+
return budget.allocateString(flags);
|
|
55
|
+
budget.visitNode();
|
|
56
|
+
const [key, flag] = entries[index];
|
|
57
|
+
const descriptor = context?.getProperty === undefined
|
|
58
|
+
? getSandboxPropertyDescriptor(target, key, budget) : undefined;
|
|
59
|
+
const value = context?.getProperty !== undefined
|
|
60
|
+
? context.getProperty(target, key)
|
|
61
|
+
: descriptor !== undefined
|
|
62
|
+
? readPropertyDescriptor(descriptor, target, context)
|
|
63
|
+
: target.flags.includes(flag);
|
|
64
|
+
const append = (value) => {
|
|
65
|
+
if (value)
|
|
66
|
+
flags += flag;
|
|
67
|
+
return read(index + 1);
|
|
68
|
+
};
|
|
69
|
+
return value instanceof Promise ? value.then(append) : append(value);
|
|
70
|
+
};
|
|
71
|
+
try {
|
|
72
|
+
const result = read(0);
|
|
73
|
+
if (result instanceof Promise)
|
|
74
|
+
return result.finally(release);
|
|
75
|
+
release();
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
release();
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
20
82
|
}
|
|
21
83
|
if (property === "lastIndex")
|
|
22
84
|
return target.lastIndex;
|
|
@@ -27,7 +89,7 @@ export function getRegexMember(target, property, budget) {
|
|
|
27
89
|
}
|
|
28
90
|
return createSandboxClosure({
|
|
29
91
|
sandbox: true,
|
|
30
|
-
name: `RegExp#${property}`,
|
|
92
|
+
name: property === "toString" ? "toString" : `RegExp#${property}`,
|
|
31
93
|
call: (args, context) => callRegexMethod(context?.thisValue, property, args, budget, context)
|
|
32
94
|
});
|
|
33
95
|
}
|
|
@@ -66,13 +128,18 @@ function escapeRegexSource(source, budget) {
|
|
|
66
128
|
text = text === "" ? "(?:)" : text;
|
|
67
129
|
return budget === undefined ? text : budget.allocateString(text);
|
|
68
130
|
}
|
|
69
|
-
export function setRegexMember(target, property, value) {
|
|
70
|
-
|
|
131
|
+
export function setRegexMember(target, property, value, budget) {
|
|
132
|
+
const properties = getRegexProperties(target);
|
|
133
|
+
if (!hasExplicitSandboxPrototype(target) && getSandboxPrototype(target, budget) === null && !Object.hasOwn(properties, property) &&
|
|
134
|
+
(property === "source" || property === "flags" || Object.hasOwn(regexFlagProperties, property))) {
|
|
71
135
|
throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
72
136
|
}
|
|
73
|
-
|
|
137
|
+
if (!Reflect.set(properties, property, value))
|
|
138
|
+
throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
74
139
|
}
|
|
75
140
|
export async function callRegexMethod(target, methodName, args, budget, context) {
|
|
141
|
+
if (methodName === "toString")
|
|
142
|
+
return regexToString(target, budget, context);
|
|
76
143
|
if (target === null || typeof target !== "object" || (methodName === "exec" && !isSandboxRegex(target))) {
|
|
77
144
|
throw new TypeError(`RegExp#${methodName} requires ${methodName === "exec" ? "a regex" : "an object"} receiver.`);
|
|
78
145
|
}
|
|
@@ -83,29 +150,71 @@ export async function callRegexMethod(target, methodName, args, budget, context)
|
|
|
83
150
|
try {
|
|
84
151
|
const input = await sandboxString(args[0], budget, context);
|
|
85
152
|
if (methodName === "test") {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (isSandboxClosure(exec)) {
|
|
89
|
-
const result = await invokeBuiltinClosure(exec, [input], budget, context, target);
|
|
90
|
-
if (result !== null && typeof result !== "object") {
|
|
91
|
-
throw new TypeError("RegExp#test exec must return an object or null.");
|
|
92
|
-
}
|
|
93
|
-
return result !== null;
|
|
94
|
-
}
|
|
153
|
+
budget.setRetainedValues(retained, undefined);
|
|
154
|
+
return await regexExec(target, input, budget, context) !== null;
|
|
95
155
|
}
|
|
96
|
-
if (!isSandboxRegex(target))
|
|
97
|
-
throw new TypeError("RegExp execution requires a regex receiver.");
|
|
98
156
|
if (typeof args[0] !== "string")
|
|
99
157
|
convertedInput = input;
|
|
158
|
+
if (!isSandboxRegex(target))
|
|
159
|
+
throw new TypeError("RegExp execution requires a regex receiver.");
|
|
100
160
|
cursor = target.lastIndex;
|
|
101
161
|
const lastIndex = await sandboxNumber(cursor, budget, context);
|
|
102
162
|
const match = executeRegex(target, input, lastIndex);
|
|
103
|
-
return
|
|
163
|
+
return toMatchArray(match, input);
|
|
104
164
|
}
|
|
105
165
|
finally {
|
|
106
166
|
budget.setRetainedValues(retained, undefined);
|
|
107
167
|
}
|
|
108
168
|
}
|
|
169
|
+
export async function regexExec(target, input, budget, context) {
|
|
170
|
+
let exec;
|
|
171
|
+
const release = retainValues(budget, () => [target, input, exec]);
|
|
172
|
+
try {
|
|
173
|
+
const descriptor = context?.getProperty === undefined
|
|
174
|
+
? getSandboxPropertyDescriptor(target, "exec", budget) : undefined;
|
|
175
|
+
exec = await (context?.getProperty !== undefined ? context.getProperty(target, "exec")
|
|
176
|
+
: descriptor === undefined ? undefined : readPropertyDescriptor(descriptor, target, context));
|
|
177
|
+
if (isSandboxClosure(exec)) {
|
|
178
|
+
const result = await invokeBuiltinClosure(exec, [input], budget, context, target);
|
|
179
|
+
if (result !== null && typeof result !== "object")
|
|
180
|
+
throw new TypeError("RegExp exec must return an object or null.");
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
return await callRegexMethod(target, "exec", [input], budget, context);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
release();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
export async function regexToString(target, budget, context) {
|
|
190
|
+
if (target === null || typeof target !== "object")
|
|
191
|
+
throw new TypeError("RegExp#toString requires an object receiver.");
|
|
192
|
+
const read = (key) => {
|
|
193
|
+
if (context?.getProperty !== undefined)
|
|
194
|
+
return context.getProperty(target, key);
|
|
195
|
+
const descriptor = getSandboxPropertyDescriptor(target, key, budget);
|
|
196
|
+
if (descriptor !== undefined)
|
|
197
|
+
return readPropertyDescriptor(descriptor, target, context);
|
|
198
|
+
return isSandboxRegex(target) ? getRegexMember(target, key, budget, context) : undefined;
|
|
199
|
+
};
|
|
200
|
+
let sourceValue;
|
|
201
|
+
let flagsValue;
|
|
202
|
+
let source;
|
|
203
|
+
let flags;
|
|
204
|
+
const release = retainValues(budget, () => [target, sourceValue, flagsValue, source, flags]);
|
|
205
|
+
try {
|
|
206
|
+
sourceValue = await read("source");
|
|
207
|
+
source = await sandboxString(sourceValue, budget, context);
|
|
208
|
+
sourceValue = undefined;
|
|
209
|
+
flagsValue = await read("flags");
|
|
210
|
+
flags = await sandboxString(flagsValue, budget, context);
|
|
211
|
+
flagsValue = undefined;
|
|
212
|
+
return budget.allocateString(`/${source}/${flags}`);
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
release();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
109
218
|
export function executeRegex(target, input, lastIndex) {
|
|
110
219
|
const pattern = getSandboxRegexPattern(target);
|
|
111
220
|
const match = matchRegex(pattern, input, lastIndex);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Budget } from "../budget.js";
|
|
2
|
+
import { type SandboxRegExpIterator } from "../regexp-iterator.js";
|
|
3
|
+
import { type SandboxValue } from "../values.js";
|
|
4
|
+
export declare function nextRegExpIterator(iterator: SandboxRegExpIterator, budget?: Budget): {
|
|
5
|
+
value: SandboxValue;
|
|
6
|
+
done: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function getRegExpIteratorMember(property: PropertyKey, budget: Budget): SandboxValue;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { isSandboxRegExpIterator, regexpIteratorState } from "../regexp-iterator.js";
|
|
2
|
+
import { createSandboxClosure } from "../values.js";
|
|
3
|
+
import { executeRegex, toMatchArray } from "./regex.js";
|
|
4
|
+
export function nextRegExpIterator(iterator, budget) {
|
|
5
|
+
const state = regexpIteratorState(iterator);
|
|
6
|
+
budget?.visitNode();
|
|
7
|
+
if (state.exhausted)
|
|
8
|
+
return { value: undefined, done: true };
|
|
9
|
+
const matcher = state.matcher;
|
|
10
|
+
const input = state.input;
|
|
11
|
+
const match = executeRegex(matcher, input, Number(matcher.lastIndex));
|
|
12
|
+
if (match === null || !matcher.flags.includes("g")) {
|
|
13
|
+
state.exhausted = true;
|
|
14
|
+
state.matcher = undefined;
|
|
15
|
+
state.input = undefined;
|
|
16
|
+
}
|
|
17
|
+
if (match === null)
|
|
18
|
+
return { value: undefined, done: true };
|
|
19
|
+
if (!state.exhausted && match.text.length === 0) {
|
|
20
|
+
const index = Number(matcher.lastIndex);
|
|
21
|
+
const unicode = matcher.flags.includes("u") || matcher.flags.includes("v");
|
|
22
|
+
const codePoint = input.codePointAt(index);
|
|
23
|
+
matcher.lastIndex = index + (unicode && codePoint !== undefined && codePoint > 0xffff ? 2 : 1);
|
|
24
|
+
}
|
|
25
|
+
budget?.allocateArrayLength(match.captures.length + 1);
|
|
26
|
+
return { value: toMatchArray(match, input), done: false };
|
|
27
|
+
}
|
|
28
|
+
export function getRegExpIteratorMember(property, budget) {
|
|
29
|
+
if (property === Symbol.toStringTag)
|
|
30
|
+
return "RegExp String Iterator";
|
|
31
|
+
if (property === Symbol.iterator)
|
|
32
|
+
return createSandboxClosure({
|
|
33
|
+
sandbox: true,
|
|
34
|
+
name: "[Symbol.iterator]",
|
|
35
|
+
call: (_args, context) => context?.thisValue
|
|
36
|
+
});
|
|
37
|
+
if (property !== "next")
|
|
38
|
+
return undefined;
|
|
39
|
+
return createSandboxClosure({
|
|
40
|
+
sandbox: true,
|
|
41
|
+
name: "next",
|
|
42
|
+
call: (_args, context) => {
|
|
43
|
+
const receiver = context?.thisValue;
|
|
44
|
+
if (!isSandboxRegExpIterator(receiver))
|
|
45
|
+
throw new TypeError("RegExp string iterator next requires a matching receiver.");
|
|
46
|
+
return nextRegExpIterator(receiver, budget);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -9,4 +9,6 @@ export declare function getStringIndex(property: string | number): number | unde
|
|
|
9
9
|
export declare function isStringMethodName(property: string | number): property is StringMethodName;
|
|
10
10
|
export declare function validateStringMethodArguments(_methodName: StringMethodName, _args: readonly Expression[]): void;
|
|
11
11
|
export declare function callStringMethod(value: SandboxValue, methodName: StringMethodName, args: readonly SandboxValue[], budget: Budget, callClosure?: (closure: SandboxClosure, args: readonly SandboxValue[]) => Promise<SandboxValue>, parent?: CompileScope, context?: SandboxCallContext): SandboxValue | Promise<SandboxValue>;
|
|
12
|
+
export declare function regexReplace(input: SandboxValue, regex: SandboxValue, replacementInput: SandboxValue, budget: Budget, callClosure: (closure: SandboxClosure, args: readonly SandboxValue[]) => Promise<SandboxValue>, context?: SandboxCallContext): Promise<string>;
|
|
13
|
+
export declare function regexMatch(input: SandboxValue, regex: SandboxValue, budget: Budget, context?: SandboxCallContext): Promise<SandboxValue>;
|
|
12
14
|
export {};
|