poe-code 14.0.56 → 14.0.58
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 +401 -341
- 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-SRYQTOX4.js → chunk-3VTLNK4E.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-XI33TU4X.js → chunk-DHD453E5.js} +393 -336
- package/packages/safe-js/dist/chunks/chunk-DHD453E5.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/index.js +2 -2
- package/packages/safe-js/dist/interp/globals/misc.js +20 -7
- package/packages/safe-js/dist/interp/interpreter.js +194 -213
- package/packages/safe-js/dist/interp/methods/regex.d.ts +1 -1
- package/packages/safe-js/dist/interp/methods/regex.js +18 -6
- package/packages/safe-js/dist/interp/methods/string.js +59 -26
- package/packages/safe-js/dist/interp/regex/engine.d.ts +1 -0
- package/packages/safe-js/dist/interp/regex/engine.js +3 -3
- package/packages/safe-js/dist/interp/resources.d.ts +1 -0
- package/packages/safe-js/dist/interp/resources.js +4 -0
- package/packages/safe-js/dist/interp/values.d.ts +6 -3
- package/packages/safe-js/dist/interp/values.js +19 -6
- package/packages/safe-js/dist/realm.js +6 -2
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +1 -1
- package/packages/safe-js/dist/snapshot/replay-data.js +4 -4
- package/packages/safe-js/dist/snapshot/restore.js +8 -0
- package/packages/safe-js/dist/snapshot/serialize.d.ts +6 -1
- package/packages/safe-js/dist/snapshot/serialize.js +14 -1
- package/packages/safe-js/dist/snapshot/validation.js +8 -2
- package/packages/safe-js/dist/chunks/chunk-XI33TU4X.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-SRYQTOX4.js.map → chunk-3VTLNK4E.js.map} +0 -0
|
@@ -7623,7 +7623,7 @@ function validateTaggedValue(record2, path, state) {
|
|
|
7623
7623
|
case "undefined":
|
|
7624
7624
|
return;
|
|
7625
7625
|
case "number":
|
|
7626
|
-
if (!["-Infinity", "Infinity", "NaN"].includes(String(record2.value))) {
|
|
7626
|
+
if (!["-Infinity", "Infinity", "NaN", "-0"].includes(String(record2.value))) {
|
|
7627
7627
|
fail("invalidValue", `${path}.value`, "unknown non-finite number value");
|
|
7628
7628
|
}
|
|
7629
7629
|
return;
|
|
@@ -7645,6 +7645,11 @@ function validateTaggedValue(record2, path, state) {
|
|
|
7645
7645
|
requireString(record2.flags, `${path}.flags`, state.limits);
|
|
7646
7646
|
requireSafeInteger(record2.lastIndex, `${path}.lastIndex`, 0);
|
|
7647
7647
|
return;
|
|
7648
|
+
case "regex-object":
|
|
7649
|
+
requireString(record2.source, `${path}.source`, state.limits);
|
|
7650
|
+
requireString(record2.flags, `${path}.flags`, state.limits);
|
|
7651
|
+
if (!Object.hasOwn(record2, "lastIndex")) fail("invalidValue", `${path}.lastIndex`, "missing regex cursor");
|
|
7652
|
+
return;
|
|
7648
7653
|
case "array":
|
|
7649
7654
|
case "arguments":
|
|
7650
7655
|
case "object":
|
|
@@ -8472,10 +8477,10 @@ function charge(context) {
|
|
|
8472
8477
|
allocateRegexSteps(context.steps);
|
|
8473
8478
|
}
|
|
8474
8479
|
function normalizeLastIndex(lastIndex) {
|
|
8475
|
-
if (
|
|
8480
|
+
if (Number.isNaN(lastIndex) || lastIndex <= 0) {
|
|
8476
8481
|
return 0;
|
|
8477
8482
|
}
|
|
8478
|
-
return Math.floor(lastIndex);
|
|
8483
|
+
return Math.min(Math.floor(lastIndex), Number.MAX_SAFE_INTEGER);
|
|
8479
8484
|
}
|
|
8480
8485
|
function charactersEqual(left, right, ignoreCase) {
|
|
8481
8486
|
return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
|
|
@@ -8508,6 +8513,16 @@ function isLineTerminator(character) {
|
|
|
8508
8513
|
|
|
8509
8514
|
// packages/safe-js/src/interp/methods/regex.ts
|
|
8510
8515
|
var regexMethodNames = /* @__PURE__ */ new Set(["exec", "test"]);
|
|
8516
|
+
var regexFlagProperties = {
|
|
8517
|
+
hasIndices: "d",
|
|
8518
|
+
global: "g",
|
|
8519
|
+
ignoreCase: "i",
|
|
8520
|
+
multiline: "m",
|
|
8521
|
+
dotAll: "s",
|
|
8522
|
+
unicode: "u",
|
|
8523
|
+
unicodeSets: "v",
|
|
8524
|
+
sticky: "y"
|
|
8525
|
+
};
|
|
8511
8526
|
function isRegexMethodName(property) {
|
|
8512
8527
|
return typeof property === "string" && regexMethodNames.has(property);
|
|
8513
8528
|
}
|
|
@@ -8518,6 +8533,7 @@ function getRegexMember(target, property, budget) {
|
|
|
8518
8533
|
return budget === void 0 ? flags : budget.allocateString(flags);
|
|
8519
8534
|
}
|
|
8520
8535
|
if (property === "lastIndex") return target.lastIndex;
|
|
8536
|
+
if (Object.hasOwn(regexFlagProperties, property)) return target.flags.includes(regexFlagProperties[property]);
|
|
8521
8537
|
if (!isRegexMethodName(property)) {
|
|
8522
8538
|
return void 0;
|
|
8523
8539
|
}
|
|
@@ -8552,14 +8568,16 @@ function setRegexMember(target, property, value) {
|
|
|
8552
8568
|
if (property !== "lastIndex") {
|
|
8553
8569
|
throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
8554
8570
|
}
|
|
8555
|
-
target.lastIndex =
|
|
8571
|
+
target.lastIndex = value;
|
|
8556
8572
|
}
|
|
8557
8573
|
async function callRegexMethod(target, methodName, args, budget, context) {
|
|
8558
8574
|
if (target === null || typeof target !== "object" || methodName === "exec" && !isSandboxRegex(target)) {
|
|
8559
8575
|
throw new TypeError(`RegExp#${methodName} requires ${methodName === "exec" ? "a regex" : "an object"} receiver.`);
|
|
8560
8576
|
}
|
|
8561
8577
|
const retained = {};
|
|
8562
|
-
|
|
8578
|
+
let cursor;
|
|
8579
|
+
let convertedInput;
|
|
8580
|
+
budget.setRetainedValues(retained, () => [target, ...args, cursor, convertedInput]);
|
|
8563
8581
|
try {
|
|
8564
8582
|
const input = await sandboxString(args[0], budget, context);
|
|
8565
8583
|
if (methodName === "test") {
|
|
@@ -8573,15 +8591,18 @@ async function callRegexMethod(target, methodName, args, budget, context) {
|
|
|
8573
8591
|
}
|
|
8574
8592
|
}
|
|
8575
8593
|
if (!isSandboxRegex(target)) throw new TypeError("RegExp execution requires a regex receiver.");
|
|
8576
|
-
|
|
8594
|
+
if (typeof args[0] !== "string") convertedInput = input;
|
|
8595
|
+
cursor = target.lastIndex;
|
|
8596
|
+
const lastIndex = await sandboxNumber(cursor, budget, context);
|
|
8597
|
+
const match = executeRegex(target, input, lastIndex);
|
|
8577
8598
|
return methodName === "test" ? match !== null : toMatchArray(match, input);
|
|
8578
8599
|
} finally {
|
|
8579
8600
|
budget.setRetainedValues(retained, void 0);
|
|
8580
8601
|
}
|
|
8581
8602
|
}
|
|
8582
|
-
function executeRegex(target, input) {
|
|
8603
|
+
function executeRegex(target, input, lastIndex) {
|
|
8583
8604
|
const pattern = getSandboxRegexPattern(target);
|
|
8584
|
-
const match = matchRegex(pattern, input,
|
|
8605
|
+
const match = matchRegex(pattern, input, lastIndex);
|
|
8585
8606
|
if (pattern.flags.global) {
|
|
8586
8607
|
target.lastIndex = match === null ? 0 : match.index + match.text.length;
|
|
8587
8608
|
}
|
|
@@ -10505,13 +10526,14 @@ function deepCopyToSandbox(value) {
|
|
|
10505
10526
|
seen: /* @__PURE__ */ new WeakMap()
|
|
10506
10527
|
});
|
|
10507
10528
|
}
|
|
10508
|
-
function cloneSandboxValue(value) {
|
|
10529
|
+
function cloneSandboxValue(value, options = {}) {
|
|
10509
10530
|
const initializeIterators = [];
|
|
10510
10531
|
const copy = copyToSandbox(
|
|
10511
10532
|
value,
|
|
10512
10533
|
{
|
|
10513
10534
|
seen: /* @__PURE__ */ new WeakMap(),
|
|
10514
|
-
initializeIterators
|
|
10535
|
+
initializeIterators,
|
|
10536
|
+
...options
|
|
10515
10537
|
},
|
|
10516
10538
|
"<root>",
|
|
10517
10539
|
true
|
|
@@ -10610,11 +10632,12 @@ function measureSandboxData(values, options = {}) {
|
|
|
10610
10632
|
}
|
|
10611
10633
|
if (isSandboxPromise(value)) return;
|
|
10612
10634
|
if (isSandboxRegex(value)) {
|
|
10613
|
-
const { source, flags } = captureRegexData(value);
|
|
10635
|
+
const { source, flags, lastIndex } = captureRegexData(value);
|
|
10614
10636
|
const compiled = regexCompiledData(getSandboxRegexPattern(value));
|
|
10615
10637
|
const staged = compiled.ticket === void 0 ? 0 : compiled.ticket.owner.budget.compileTicketUsage(compiled.ticket);
|
|
10616
10638
|
usage += Math.max(6 + source.length + flags.length + compiled.units, staged - 1);
|
|
10617
10639
|
if (compiled.ticket !== void 0) options.compileTickets?.add(compiled.ticket);
|
|
10640
|
+
visit(lastIndex, depth + 1);
|
|
10618
10641
|
return;
|
|
10619
10642
|
}
|
|
10620
10643
|
if (isSandboxArguments(value)) {
|
|
@@ -10695,7 +10718,16 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
10695
10718
|
return value;
|
|
10696
10719
|
}
|
|
10697
10720
|
if (isLiveCapability(value)) throw new TypeError("Live capabilities require their owning realm bridge.");
|
|
10698
|
-
if (
|
|
10721
|
+
if (isSandboxRegex(value)) {
|
|
10722
|
+
if (!cloneSandboxCollections) return value;
|
|
10723
|
+
const existing = state.seen.get(value);
|
|
10724
|
+
if (existing !== void 0) return existing;
|
|
10725
|
+
const copy = createSandboxRegex(value.source, value.flags, 0, state.compilation);
|
|
10726
|
+
state.seen.set(value, copy);
|
|
10727
|
+
if (!state.resetRegexLastIndex) copy.lastIndex = copyToSandbox(value.lastIndex, state, `${path}.lastIndex`, true, depth + 1);
|
|
10728
|
+
return copy;
|
|
10729
|
+
}
|
|
10730
|
+
if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxPromise(value)) {
|
|
10699
10731
|
return value;
|
|
10700
10732
|
}
|
|
10701
10733
|
if (isSandboxCollectionIterator(value)) {
|
|
@@ -10904,9 +10936,9 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
10904
10936
|
if (existing !== void 0) return existing;
|
|
10905
10937
|
guard.allocate(1 + source.length + flags.length);
|
|
10906
10938
|
const regex = new RegExp(source, flags);
|
|
10907
|
-
regex.lastIndex = lastIndex;
|
|
10908
|
-
guard.retainScratch();
|
|
10909
10939
|
state.seen.set(value, regex);
|
|
10940
|
+
Reflect.set(regex, "lastIndex", copyFromSandbox(lastIndex, state, `${path}.lastIndex`, options, depth + 1));
|
|
10941
|
+
guard.retainScratch();
|
|
10910
10942
|
return regex;
|
|
10911
10943
|
} finally {
|
|
10912
10944
|
guard.close();
|
|
@@ -11293,7 +11325,7 @@ function encodeReplayData(value, options = {}) {
|
|
|
11293
11325
|
kind: "regex",
|
|
11294
11326
|
source: entry.source,
|
|
11295
11327
|
flags: entry.flags,
|
|
11296
|
-
lastIndex: entry.lastIndex
|
|
11328
|
+
lastIndex: child(entry.lastIndex, "lastIndex")
|
|
11297
11329
|
};
|
|
11298
11330
|
} else if (isSandboxArguments(entry)) {
|
|
11299
11331
|
nodes[id] = { kind: "arguments", data: serializeArguments(entry, child) };
|
|
@@ -11460,11 +11492,12 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
11460
11492
|
return result3;
|
|
11461
11493
|
}
|
|
11462
11494
|
if (kind === "regex") {
|
|
11463
|
-
if (typeof node.source !== "string" || typeof node.flags !== "string" ||
|
|
11495
|
+
if (typeof node.source !== "string" || typeof node.flags !== "string" || !Object.hasOwn(node, "lastIndex")) {
|
|
11464
11496
|
throw new TypeError("Invalid replay regular expression.");
|
|
11465
11497
|
}
|
|
11466
|
-
const result3 = createSandboxRegex(node.source, node.flags,
|
|
11498
|
+
const result3 = createSandboxRegex(node.source, node.flags, 0, compilation);
|
|
11467
11499
|
restored.set(id, result3);
|
|
11500
|
+
result3.lastIndex = child(own(node, "lastIndex"));
|
|
11468
11501
|
return result3;
|
|
11469
11502
|
}
|
|
11470
11503
|
if (kind === "arguments") {
|
|
@@ -23847,6 +23880,44 @@ function hoistVarDeclarations(node, scope) {
|
|
|
23847
23880
|
}
|
|
23848
23881
|
}
|
|
23849
23882
|
|
|
23883
|
+
// packages/safe-js/src/interp/resources.ts
|
|
23884
|
+
import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
|
|
23885
|
+
var runResources = new AsyncLocalStorage5();
|
|
23886
|
+
async function withRunResources(signal, execute) {
|
|
23887
|
+
const controller = new AbortController();
|
|
23888
|
+
const cancel = () => controller.abort(signal?.reason);
|
|
23889
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
23890
|
+
const resources = {
|
|
23891
|
+
signal: controller.signal,
|
|
23892
|
+
referenceReleases: /* @__PURE__ */ new Set(),
|
|
23893
|
+
add(close) {
|
|
23894
|
+
cleanups.add(close);
|
|
23895
|
+
}
|
|
23896
|
+
};
|
|
23897
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
23898
|
+
if (signal?.aborted) cancel();
|
|
23899
|
+
let result;
|
|
23900
|
+
let failure;
|
|
23901
|
+
let errors = [];
|
|
23902
|
+
try {
|
|
23903
|
+
result = await runResources.run(resources, execute);
|
|
23904
|
+
} catch (error) {
|
|
23905
|
+
failure = { reason: error };
|
|
23906
|
+
} finally {
|
|
23907
|
+
signal?.removeEventListener("abort", cancel);
|
|
23908
|
+
controller.abort(new Error("SafeJS run finished."));
|
|
23909
|
+
for (const release of resources.referenceReleases) release();
|
|
23910
|
+
resources.referenceReleases.clear();
|
|
23911
|
+
const outcomes = await Promise.allSettled(
|
|
23912
|
+
[...cleanups].map((close) => Promise.resolve().then(close))
|
|
23913
|
+
);
|
|
23914
|
+
errors = outcomes.flatMap((outcome) => outcome.status === "rejected" ? [outcome.reason] : []);
|
|
23915
|
+
}
|
|
23916
|
+
if (failure !== void 0) throw failure.reason;
|
|
23917
|
+
if (errors.length > 0) throw new AggregateError(errors, "SafeJS resource cleanup failed.");
|
|
23918
|
+
return result;
|
|
23919
|
+
}
|
|
23920
|
+
|
|
23850
23921
|
// packages/safe-js/src/interp/methods/array.ts
|
|
23851
23922
|
var arrayLikeSources = /* @__PURE__ */ new WeakMap();
|
|
23852
23923
|
var activeArrayCallbacks = /* @__PURE__ */ new WeakMap();
|
|
@@ -25029,7 +25100,11 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
|
|
|
25029
25100
|
return budget.allocateString(result + value.slice(spanStart));
|
|
25030
25101
|
}
|
|
25031
25102
|
if (methodName === "replace" || methodName === "replaceAll") {
|
|
25032
|
-
return callReplaceLikeMethod(value, methodName, args, budget, callClosure);
|
|
25103
|
+
return callReplaceLikeMethod(value, methodName, args, budget, callClosure, context);
|
|
25104
|
+
}
|
|
25105
|
+
const regex = args[0];
|
|
25106
|
+
if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll" && regex.flags.includes("g"))) {
|
|
25107
|
+
return callStringRegexCursor(value, methodName, regex, budget, parent, context);
|
|
25033
25108
|
}
|
|
25034
25109
|
if ((methodName === "match" || methodName === "matchAll" || methodName === "search") && !isSandboxRegex(args[0])) {
|
|
25035
25110
|
return callStringPattern(value, methodName, args[0], budget, parent, context);
|
|
@@ -25144,7 +25219,7 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
|
|
|
25144
25219
|
operation.release();
|
|
25145
25220
|
}
|
|
25146
25221
|
}
|
|
25147
|
-
function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
|
|
25222
|
+
function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
|
|
25148
25223
|
const search = args[0];
|
|
25149
25224
|
const replacement = args[1];
|
|
25150
25225
|
if (!isSandboxRegex(search) && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
|
|
@@ -25162,7 +25237,8 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
|
|
|
25162
25237
|
replacement,
|
|
25163
25238
|
methodName === "replaceAll",
|
|
25164
25239
|
budget,
|
|
25165
|
-
callClosure
|
|
25240
|
+
callClosure,
|
|
25241
|
+
context
|
|
25166
25242
|
);
|
|
25167
25243
|
}
|
|
25168
25244
|
if (typeof replacement === "string") {
|
|
@@ -25179,20 +25255,28 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure) {
|
|
|
25179
25255
|
callClosure
|
|
25180
25256
|
);
|
|
25181
25257
|
}
|
|
25182
|
-
async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure) {
|
|
25258
|
+
async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure, context) {
|
|
25183
25259
|
if (regex.flags.includes("g")) regex.lastIndex = 0;
|
|
25184
|
-
const
|
|
25185
|
-
|
|
25186
|
-
|
|
25187
|
-
|
|
25188
|
-
|
|
25189
|
-
|
|
25190
|
-
|
|
25191
|
-
|
|
25192
|
-
|
|
25260
|
+
const cursor = regex.lastIndex;
|
|
25261
|
+
const retained = {};
|
|
25262
|
+
budget.setRetainedValues(retained, () => [value, regex, cursor, replacement]);
|
|
25263
|
+
try {
|
|
25264
|
+
const lastIndex = await sandboxNumber(cursor, budget, context);
|
|
25265
|
+
const matches = collectRegexMatches(regex, value, replaceAll || regex.flags.includes("g"), void 0, lastIndex);
|
|
25266
|
+
let result = "";
|
|
25267
|
+
let copiedThrough = 0;
|
|
25268
|
+
for (const match of matches) {
|
|
25269
|
+
result += value.slice(copiedThrough, match.index);
|
|
25270
|
+
result += typeof replacement === "string" ? expandReplacement(replacement, match.text, match.captures, value, match.index) : String(
|
|
25271
|
+
await callClosure(replacement, [match.text, ...match.captures, match.index, value])
|
|
25272
|
+
);
|
|
25273
|
+
copiedThrough = match.index + match.text.length;
|
|
25274
|
+
}
|
|
25275
|
+
result += value.slice(copiedThrough);
|
|
25276
|
+
return budget.allocateString(result);
|
|
25277
|
+
} finally {
|
|
25278
|
+
budget.setRetainedValues(retained, void 0);
|
|
25193
25279
|
}
|
|
25194
|
-
result += value.slice(copiedThrough);
|
|
25195
|
-
return budget.allocateString(result);
|
|
25196
25280
|
}
|
|
25197
25281
|
function expandReplacement(replacement, match, captures, input, matchIndex) {
|
|
25198
25282
|
let result = "";
|
|
@@ -25308,7 +25392,7 @@ async function callStringPattern(value, methodName, pattern, budget, parent, con
|
|
|
25308
25392
|
const operation = budget.acquireCompileOwner(false, parent?.owner);
|
|
25309
25393
|
const compilation = new CompileScope(operation.owner);
|
|
25310
25394
|
const retainedPattern = {};
|
|
25311
|
-
budget.setRetainedValues(retainedPattern, () => [pattern]);
|
|
25395
|
+
budget.setRetainedValues(retainedPattern, () => [value, pattern]);
|
|
25312
25396
|
try {
|
|
25313
25397
|
const source = pattern === void 0 ? "" : await sandboxString(pattern, budget, context);
|
|
25314
25398
|
const regex = createSandboxRegex(source, methodName === "matchAll" ? "g" : "", 0, compilation);
|
|
@@ -25319,35 +25403,51 @@ async function callStringPattern(value, methodName, pattern, budget, parent, con
|
|
|
25319
25403
|
operation.release();
|
|
25320
25404
|
}
|
|
25321
25405
|
}
|
|
25322
|
-
function
|
|
25406
|
+
async function callStringRegexCursor(value, methodName, regex, budget, parent, context) {
|
|
25407
|
+
const operation = budget.acquireCompileOwner(false, parent?.owner);
|
|
25408
|
+
const compilation = new CompileScope(operation.owner);
|
|
25409
|
+
const cursor = regex.lastIndex;
|
|
25410
|
+
const retained = {};
|
|
25411
|
+
budget.setRetainedValues(retained, () => [value, regex, cursor]);
|
|
25412
|
+
try {
|
|
25413
|
+
const lastIndex = await sandboxNumber(cursor, budget, context);
|
|
25414
|
+
return callMatchLikeMethod(value, methodName, [regex], compilation, lastIndex);
|
|
25415
|
+
} finally {
|
|
25416
|
+
budget.setRetainedValues(retained, void 0);
|
|
25417
|
+
compilation.dispose();
|
|
25418
|
+
operation.release();
|
|
25419
|
+
}
|
|
25420
|
+
}
|
|
25421
|
+
function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
|
|
25323
25422
|
const regex = args[0];
|
|
25324
25423
|
if (!isSandboxRegex(regex))
|
|
25325
25424
|
throw new TypeError(`String#${methodName} requires a regex argument.`);
|
|
25326
25425
|
if (methodName === "search") {
|
|
25327
|
-
const
|
|
25328
|
-
if (!Object.is(
|
|
25329
|
-
const match = executeRegex(regex, value);
|
|
25330
|
-
if (!Object.is(regex.lastIndex,
|
|
25426
|
+
const lastIndex2 = regex.lastIndex;
|
|
25427
|
+
if (!Object.is(lastIndex2, 0)) regex.lastIndex = 0;
|
|
25428
|
+
const match = executeRegex(regex, value, 0);
|
|
25429
|
+
if (!Object.is(regex.lastIndex, lastIndex2)) regex.lastIndex = lastIndex2;
|
|
25331
25430
|
return match?.index ?? -1;
|
|
25332
25431
|
}
|
|
25333
25432
|
if (methodName === "matchAll" && !regex.flags.includes("g"))
|
|
25334
25433
|
throw new TypeError("String#matchAll requires a global regex.");
|
|
25335
25434
|
if (methodName === "match" && !regex.flags.includes("g"))
|
|
25336
|
-
return toMatchArray(executeRegex(regex, value), value);
|
|
25435
|
+
return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
|
|
25337
25436
|
if (methodName === "match") regex.lastIndex = 0;
|
|
25338
|
-
const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, regex.lastIndex, compilation) : regex;
|
|
25339
|
-
const matches = collectRegexMatches(matcher, value, true, compilation.owner?.budget);
|
|
25437
|
+
const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, normalizeLastIndex(lastIndex ?? Number(regex.lastIndex)), compilation) : regex;
|
|
25438
|
+
const matches = collectRegexMatches(matcher, value, true, compilation.owner?.budget, Number(matcher.lastIndex));
|
|
25340
25439
|
if (methodName === "match" && matches.length === 0) return null;
|
|
25341
25440
|
return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
|
|
25342
25441
|
}
|
|
25343
|
-
function collectRegexMatches(regex, value, all, budget) {
|
|
25442
|
+
function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
|
|
25344
25443
|
const matches = [];
|
|
25345
25444
|
do {
|
|
25346
|
-
const match = executeRegex(regex, value);
|
|
25445
|
+
const match = executeRegex(regex, value, lastIndex);
|
|
25347
25446
|
if (match === null) break;
|
|
25348
25447
|
budget?.allocateArrayLength(matches.length + 1);
|
|
25349
25448
|
matches.push(match);
|
|
25350
|
-
|
|
25449
|
+
lastIndex = match.index + match.text.length;
|
|
25450
|
+
if (all && match.text.length === 0) regex.lastIndex = ++lastIndex;
|
|
25351
25451
|
} while (all);
|
|
25352
25452
|
return matches;
|
|
25353
25453
|
}
|
|
@@ -26754,61 +26854,56 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
26754
26854
|
if (node.left.type !== "MemberExpression") {
|
|
26755
26855
|
throw new TypeError("Expected member assignment target.");
|
|
26756
26856
|
}
|
|
26757
|
-
|
|
26758
|
-
|
|
26759
|
-
|
|
26760
|
-
|
|
26761
|
-
|
|
26762
|
-
|
|
26763
|
-
|
|
26764
|
-
|
|
26765
|
-
|
|
26766
|
-
|
|
26767
|
-
|
|
26768
|
-
|
|
26769
|
-
|
|
26857
|
+
return evaluateMemberAccess(node.left, context, async (member) => {
|
|
26858
|
+
if (member.kind === "nullish") {
|
|
26859
|
+
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26860
|
+
}
|
|
26861
|
+
let property;
|
|
26862
|
+
let current = void 0;
|
|
26863
|
+
if (node.operator !== "=") {
|
|
26864
|
+
if (member.object === null || member.object === void 0) {
|
|
26865
|
+
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26866
|
+
}
|
|
26867
|
+
property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
26868
|
+
current = getPropertyValue(member.object, property, context);
|
|
26869
|
+
}
|
|
26870
|
+
if (node.operator === "&&=" && !isTruthy(current)) {
|
|
26871
|
+
return {
|
|
26872
|
+
kind: "normal",
|
|
26873
|
+
hasValue: true,
|
|
26874
|
+
value: current
|
|
26875
|
+
};
|
|
26876
|
+
}
|
|
26877
|
+
if (node.operator === "||=" && isTruthy(current)) {
|
|
26878
|
+
return {
|
|
26879
|
+
kind: "normal",
|
|
26880
|
+
hasValue: true,
|
|
26881
|
+
value: current
|
|
26882
|
+
};
|
|
26883
|
+
}
|
|
26884
|
+
if (node.operator === "??=" && current !== null && current !== void 0) {
|
|
26885
|
+
return {
|
|
26886
|
+
kind: "normal",
|
|
26887
|
+
hasValue: true,
|
|
26888
|
+
value: current
|
|
26889
|
+
};
|
|
26890
|
+
}
|
|
26891
|
+
const right = await evaluateNode(node.right, context);
|
|
26892
|
+
if (right.kind !== "normal") {
|
|
26893
|
+
return right;
|
|
26894
|
+
}
|
|
26895
|
+
const value = node.operator === "=" || node.operator === "&&=" || node.operator === "||=" || node.operator === "??=" ? right.value : await applyCompoundAssignmentOperator(node.operator, current, right.value, context);
|
|
26770
26896
|
if (member.object === null || member.object === void 0) {
|
|
26771
26897
|
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26772
26898
|
}
|
|
26773
|
-
property
|
|
26774
|
-
|
|
26775
|
-
}
|
|
26776
|
-
if (node.operator === "&&=" && !isTruthy(current)) {
|
|
26899
|
+
property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
26900
|
+
setSandboxProperty(member.object, property, value, context.budget);
|
|
26777
26901
|
return {
|
|
26778
26902
|
kind: "normal",
|
|
26779
26903
|
hasValue: true,
|
|
26780
|
-
value
|
|
26781
|
-
};
|
|
26782
|
-
}
|
|
26783
|
-
if (node.operator === "||=" && isTruthy(current)) {
|
|
26784
|
-
return {
|
|
26785
|
-
kind: "normal",
|
|
26786
|
-
hasValue: true,
|
|
26787
|
-
value: current
|
|
26788
|
-
};
|
|
26789
|
-
}
|
|
26790
|
-
if (node.operator === "??=" && current !== null && current !== void 0) {
|
|
26791
|
-
return {
|
|
26792
|
-
kind: "normal",
|
|
26793
|
-
hasValue: true,
|
|
26794
|
-
value: current
|
|
26904
|
+
value
|
|
26795
26905
|
};
|
|
26796
|
-
}
|
|
26797
|
-
const right = await evaluateNode(node.right, context);
|
|
26798
|
-
if (right.kind !== "normal") {
|
|
26799
|
-
return right;
|
|
26800
|
-
}
|
|
26801
|
-
const value = node.operator === "=" || node.operator === "&&=" || node.operator === "||=" || node.operator === "??=" ? right.value : await applyCompoundAssignmentOperator(node.operator, current, right.value, context);
|
|
26802
|
-
if (member.object === null || member.object === void 0) {
|
|
26803
|
-
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26804
|
-
}
|
|
26805
|
-
property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
26806
|
-
setSandboxProperty(member.object, property, value, context.budget);
|
|
26807
|
-
return {
|
|
26808
|
-
kind: "normal",
|
|
26809
|
-
hasValue: true,
|
|
26810
|
-
value
|
|
26811
|
-
};
|
|
26906
|
+
});
|
|
26812
26907
|
}
|
|
26813
26908
|
async function evaluateLogicalExpression(node, context) {
|
|
26814
26909
|
const left = await evaluateNode(node.left, context);
|
|
@@ -27787,33 +27882,28 @@ async function evaluateDeleteExpression(node, context) {
|
|
|
27787
27882
|
"Unary operator 'delete' requires a member target."
|
|
27788
27883
|
);
|
|
27789
27884
|
}
|
|
27790
|
-
|
|
27791
|
-
|
|
27792
|
-
|
|
27793
|
-
|
|
27794
|
-
|
|
27795
|
-
|
|
27796
|
-
|
|
27797
|
-
|
|
27798
|
-
|
|
27799
|
-
|
|
27800
|
-
kind: "normal",
|
|
27801
|
-
hasValue: true,
|
|
27802
|
-
value: true
|
|
27803
|
-
};
|
|
27885
|
+
return evaluateMemberAccess(node.argument, context, async (member) => {
|
|
27886
|
+
if (member.kind === "nullish" || member.object === null || member.object === void 0) {
|
|
27887
|
+
if (member.kind === "nullish") {
|
|
27888
|
+
return {
|
|
27889
|
+
kind: "normal",
|
|
27890
|
+
hasValue: true,
|
|
27891
|
+
value: true
|
|
27892
|
+
};
|
|
27893
|
+
}
|
|
27894
|
+
throw new TypeError("Cannot delete properties of null or undefined.");
|
|
27804
27895
|
}
|
|
27805
|
-
|
|
27806
|
-
|
|
27807
|
-
|
|
27808
|
-
|
|
27809
|
-
|
|
27810
|
-
|
|
27811
|
-
|
|
27812
|
-
|
|
27813
|
-
|
|
27814
|
-
|
|
27815
|
-
|
|
27816
|
-
};
|
|
27896
|
+
if (!isIndexableSandboxValue(member.object)) {
|
|
27897
|
+
throw new TypeError("Unary operator 'delete' requires a sandbox object property.");
|
|
27898
|
+
}
|
|
27899
|
+
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
27900
|
+
const deleted = deleteSandboxProperty(member.object, property);
|
|
27901
|
+
return {
|
|
27902
|
+
kind: "normal",
|
|
27903
|
+
hasValue: true,
|
|
27904
|
+
value: deleted
|
|
27905
|
+
};
|
|
27906
|
+
});
|
|
27817
27907
|
}
|
|
27818
27908
|
async function evaluateUpdateExpression(node, context) {
|
|
27819
27909
|
if (node.argument.type === "Identifier") {
|
|
@@ -27849,41 +27939,35 @@ async function evaluateMemberUpdateExpression(node, context) {
|
|
|
27849
27939
|
if (node.argument.type !== "MemberExpression") {
|
|
27850
27940
|
throw new TypeError("Expected member update target.");
|
|
27851
27941
|
}
|
|
27852
|
-
|
|
27853
|
-
|
|
27854
|
-
|
|
27855
|
-
|
|
27856
|
-
|
|
27857
|
-
|
|
27858
|
-
|
|
27859
|
-
|
|
27860
|
-
|
|
27861
|
-
|
|
27862
|
-
|
|
27863
|
-
|
|
27864
|
-
|
|
27865
|
-
|
|
27866
|
-
|
|
27867
|
-
|
|
27868
|
-
return {
|
|
27869
|
-
kind: "normal",
|
|
27870
|
-
hasValue: true,
|
|
27871
|
-
value: node.prefix ? next : current
|
|
27872
|
-
};
|
|
27942
|
+
return evaluateMemberAccess(node.argument, context, async (member) => {
|
|
27943
|
+
if (member.kind === "nullish" || member.object === null || member.object === void 0) {
|
|
27944
|
+
throw new TypeError("Cannot update properties of null or undefined.");
|
|
27945
|
+
}
|
|
27946
|
+
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
27947
|
+
const current = toNumber(
|
|
27948
|
+
await toNumericPrimitive(getPropertyValue(member.object, property, context), context)
|
|
27949
|
+
);
|
|
27950
|
+
const next = node.operator === "++" ? current + 1 : current - 1;
|
|
27951
|
+
setSandboxProperty(member.object, property, next, context.budget);
|
|
27952
|
+
return {
|
|
27953
|
+
kind: "normal",
|
|
27954
|
+
hasValue: true,
|
|
27955
|
+
value: node.prefix ? next : current
|
|
27956
|
+
};
|
|
27957
|
+
});
|
|
27873
27958
|
}
|
|
27874
27959
|
async function evaluateMemberExpression(node, context) {
|
|
27875
|
-
|
|
27876
|
-
|
|
27877
|
-
|
|
27878
|
-
|
|
27879
|
-
|
|
27880
|
-
|
|
27881
|
-
|
|
27882
|
-
|
|
27883
|
-
|
|
27884
|
-
|
|
27885
|
-
|
|
27886
|
-
};
|
|
27960
|
+
return evaluateMemberAccess(node, context, async (member) => {
|
|
27961
|
+
if (member.kind === "nullish" || member.object === null || member.object === void 0) {
|
|
27962
|
+
if (member.kind === "nullish") return { kind: "normal", hasValue: true, value: void 0 };
|
|
27963
|
+
throw new TypeError("Cannot read properties of null or undefined.");
|
|
27964
|
+
}
|
|
27965
|
+
return {
|
|
27966
|
+
kind: "normal",
|
|
27967
|
+
hasValue: true,
|
|
27968
|
+
value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
|
|
27969
|
+
};
|
|
27970
|
+
});
|
|
27887
27971
|
}
|
|
27888
27972
|
function getPropertyValue(target, property, context) {
|
|
27889
27973
|
if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
|
|
@@ -27991,26 +28075,27 @@ function attachFatalSandboxErrorContext(error, node, stackFrames) {
|
|
|
27991
28075
|
attachErrorSpan(error, node.span);
|
|
27992
28076
|
replaceErrorStack(error, stackFrames);
|
|
27993
28077
|
}
|
|
27994
|
-
async function evaluateMemberAccess(node, context) {
|
|
28078
|
+
async function evaluateMemberAccess(node, context, consume) {
|
|
27995
28079
|
const object = await evaluateNode(node.object, context);
|
|
27996
|
-
if (object.kind !== "normal")
|
|
27997
|
-
return {
|
|
27998
|
-
kind: "completion",
|
|
27999
|
-
result: object
|
|
28000
|
-
};
|
|
28001
|
-
}
|
|
28080
|
+
if (object.kind !== "normal") return object;
|
|
28002
28081
|
if ((object.value === null || object.value === void 0) && node.optional) {
|
|
28003
|
-
return {
|
|
28004
|
-
|
|
28005
|
-
|
|
28082
|
+
return consume({ kind: "nullish" });
|
|
28083
|
+
}
|
|
28084
|
+
const retained = {};
|
|
28085
|
+
let property;
|
|
28086
|
+
context.budget.setRetainedValues(retained, () => [object.value, property]);
|
|
28087
|
+
const release = () => context.budget.setRetainedValues(retained, void 0);
|
|
28088
|
+
const pending = runResources.getStore()?.referenceReleases;
|
|
28089
|
+
pending?.add(release);
|
|
28090
|
+
try {
|
|
28091
|
+
const result = node.computed ? await evaluateNode(node.property, context) : { kind: "normal", value: getStaticPropertyName2(node.property) };
|
|
28092
|
+
if (result.kind !== "normal") return result;
|
|
28093
|
+
property = result.value;
|
|
28094
|
+
return await consume({ kind: "resolved", object: object.value, property });
|
|
28095
|
+
} finally {
|
|
28096
|
+
release();
|
|
28097
|
+
pending?.delete(release);
|
|
28006
28098
|
}
|
|
28007
|
-
const property = node.computed ? await evaluateNode(node.property, context) : { kind: "normal", value: getStaticPropertyName2(node.property) };
|
|
28008
|
-
if (property.kind !== "normal") return { kind: "completion", result: property };
|
|
28009
|
-
return {
|
|
28010
|
-
kind: "resolved",
|
|
28011
|
-
object: object.value,
|
|
28012
|
-
property: property.value
|
|
28013
|
-
};
|
|
28014
28099
|
}
|
|
28015
28100
|
async function evaluateMemberProperty(node, context) {
|
|
28016
28101
|
const property = await evaluateNode(node, context);
|
|
@@ -28047,137 +28132,132 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
28047
28132
|
if (node.callee.type !== "MemberExpression") {
|
|
28048
28133
|
throw new TypeError("Expected member call expression.");
|
|
28049
28134
|
}
|
|
28050
|
-
|
|
28051
|
-
|
|
28052
|
-
|
|
28053
|
-
|
|
28054
|
-
|
|
28055
|
-
|
|
28056
|
-
|
|
28057
|
-
|
|
28058
|
-
|
|
28059
|
-
|
|
28060
|
-
kind: "normal",
|
|
28061
|
-
hasValue: true,
|
|
28062
|
-
value: void 0
|
|
28063
|
-
};
|
|
28135
|
+
return evaluateMemberAccess(node.callee, context, async (reference) => {
|
|
28136
|
+
if (reference.kind === "nullish" || reference.object === null || reference.object === void 0) {
|
|
28137
|
+
if (reference.kind === "nullish") {
|
|
28138
|
+
return {
|
|
28139
|
+
kind: "normal",
|
|
28140
|
+
hasValue: true,
|
|
28141
|
+
value: void 0
|
|
28142
|
+
};
|
|
28143
|
+
}
|
|
28144
|
+
throw new TypeError("Cannot read properties of null or undefined.");
|
|
28064
28145
|
}
|
|
28065
|
-
|
|
28066
|
-
|
|
28067
|
-
|
|
28068
|
-
|
|
28069
|
-
|
|
28070
|
-
|
|
28071
|
-
if (typeof member.object === "string" && isStringMethodName(member.property)) {
|
|
28072
|
-
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
28073
|
-
}
|
|
28074
|
-
if (typeof member.object === "number" && isNumberMethodName(member.property)) {
|
|
28075
|
-
return evaluateNumberMethodCall(node, member.object, member.property, context);
|
|
28076
|
-
}
|
|
28077
|
-
if (Array.isArray(member.object) && isArrayMethodName(member.property) && !Object.hasOwn(member.object, member.property)) {
|
|
28078
|
-
return evaluateArrayMethodCall(node, member.object, member.property, context);
|
|
28079
|
-
}
|
|
28080
|
-
if (isSandboxMap(member.object) && isMapMethodName(member.property)) {
|
|
28081
|
-
return evaluateMapMethodCall(node, member.object, member.property, context);
|
|
28082
|
-
}
|
|
28083
|
-
if (isSandboxSet(member.object) && isSetMethodName(member.property)) {
|
|
28084
|
-
return evaluateSetMethodCall(node, member.object, member.property, context);
|
|
28085
|
-
}
|
|
28086
|
-
if (typeof member.object === "string") {
|
|
28087
|
-
return evaluatePrimitiveMemberCall(
|
|
28088
|
-
node,
|
|
28089
|
-
"String",
|
|
28090
|
-
member.property,
|
|
28091
|
-
getStringMember(member.object, member.property, context.budget),
|
|
28092
|
-
context
|
|
28093
|
-
);
|
|
28094
|
-
}
|
|
28095
|
-
if (typeof member.object === "number") {
|
|
28096
|
-
return evaluatePrimitiveMemberCall(
|
|
28097
|
-
node,
|
|
28098
|
-
"Number",
|
|
28099
|
-
member.property,
|
|
28100
|
-
getNumberMember(member.property, context.budget),
|
|
28101
|
-
context
|
|
28102
|
-
);
|
|
28103
|
-
}
|
|
28104
|
-
if (Array.isArray(member.object) && !Object.hasOwn(member.object, member.property)) {
|
|
28105
|
-
return evaluatePrimitiveMemberCall(
|
|
28106
|
-
node,
|
|
28107
|
-
"Array",
|
|
28108
|
-
member.property,
|
|
28109
|
-
getArrayMemberValue(member.object, member.property, context),
|
|
28110
|
-
context
|
|
28111
|
-
);
|
|
28112
|
-
}
|
|
28113
|
-
if (isSandboxMap(member.object)) {
|
|
28114
|
-
return evaluatePrimitiveMemberCall(
|
|
28115
|
-
node,
|
|
28116
|
-
"Map",
|
|
28117
|
-
member.property,
|
|
28118
|
-
getMapMember(member.object, member.property, createMapMethodOptions(context)),
|
|
28119
|
-
context
|
|
28120
|
-
);
|
|
28121
|
-
}
|
|
28122
|
-
if (isSandboxDate(member.object)) {
|
|
28123
|
-
return evaluateResolvedCallExpression(node, getDateMember(member.property, context.budget, context.compilation?.owner), context, member.object);
|
|
28124
|
-
}
|
|
28125
|
-
if (isFloat32Array(member.object)) {
|
|
28126
|
-
return evaluateResolvedCallExpression(
|
|
28127
|
-
node,
|
|
28128
|
-
getFloat32Member(member.object, member.property, context.budget),
|
|
28129
|
-
context,
|
|
28130
|
-
member.object
|
|
28131
|
-
);
|
|
28132
|
-
}
|
|
28133
|
-
if (isSandboxSet(member.object)) {
|
|
28134
|
-
return evaluatePrimitiveMemberCall(
|
|
28135
|
-
node,
|
|
28136
|
-
"Set",
|
|
28137
|
-
member.property,
|
|
28138
|
-
getSetMember(member.object, member.property, createSetMethodOptions(context)),
|
|
28139
|
-
context
|
|
28140
|
-
);
|
|
28141
|
-
}
|
|
28142
|
-
if (isSandboxGenerator(member.object)) {
|
|
28143
|
-
const memberValue = getGeneratorMember(member.object, member.property, context.budget);
|
|
28144
|
-
if (memberValue === void 0) {
|
|
28145
|
-
throw new TypeError(`Generator#${String(member.property)} is not a supported method.`);
|
|
28146
|
+
const member = {
|
|
28147
|
+
...reference,
|
|
28148
|
+
property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
|
|
28149
|
+
};
|
|
28150
|
+
if (typeof member.object === "string" && isStringMethodName(member.property)) {
|
|
28151
|
+
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
28146
28152
|
}
|
|
28147
|
-
|
|
28148
|
-
|
|
28149
|
-
|
|
28150
|
-
|
|
28151
|
-
|
|
28152
|
-
|
|
28153
|
+
if (typeof member.object === "number" && isNumberMethodName(member.property)) {
|
|
28154
|
+
return evaluateNumberMethodCall(node, member.object, member.property, context);
|
|
28155
|
+
}
|
|
28156
|
+
if (Array.isArray(member.object) && isArrayMethodName(member.property) && !Object.hasOwn(member.object, member.property)) {
|
|
28157
|
+
return evaluateArrayMethodCall(node, member.object, member.property, context);
|
|
28158
|
+
}
|
|
28159
|
+
if (isSandboxMap(member.object) && isMapMethodName(member.property)) {
|
|
28160
|
+
return evaluateMapMethodCall(node, member.object, member.property, context);
|
|
28161
|
+
}
|
|
28162
|
+
if (isSandboxSet(member.object) && isSetMethodName(member.property)) {
|
|
28163
|
+
return evaluateSetMethodCall(node, member.object, member.property, context);
|
|
28164
|
+
}
|
|
28165
|
+
if (typeof member.object === "string") {
|
|
28166
|
+
return evaluatePrimitiveMemberCall(
|
|
28167
|
+
node,
|
|
28168
|
+
"String",
|
|
28169
|
+
member.property,
|
|
28170
|
+
getStringMember(member.object, member.property, context.budget),
|
|
28171
|
+
context
|
|
28172
|
+
);
|
|
28173
|
+
}
|
|
28174
|
+
if (typeof member.object === "number") {
|
|
28175
|
+
return evaluatePrimitiveMemberCall(
|
|
28176
|
+
node,
|
|
28177
|
+
"Number",
|
|
28178
|
+
member.property,
|
|
28179
|
+
getNumberMember(member.property, context.budget),
|
|
28180
|
+
context
|
|
28181
|
+
);
|
|
28182
|
+
}
|
|
28183
|
+
if (Array.isArray(member.object) && !Object.hasOwn(member.object, member.property)) {
|
|
28184
|
+
return evaluatePrimitiveMemberCall(
|
|
28185
|
+
node,
|
|
28186
|
+
"Array",
|
|
28187
|
+
member.property,
|
|
28188
|
+
getArrayMemberValue(member.object, member.property, context),
|
|
28189
|
+
context
|
|
28190
|
+
);
|
|
28191
|
+
}
|
|
28192
|
+
if (isSandboxMap(member.object)) {
|
|
28193
|
+
return evaluatePrimitiveMemberCall(
|
|
28194
|
+
node,
|
|
28195
|
+
"Map",
|
|
28196
|
+
member.property,
|
|
28197
|
+
getMapMember(member.object, member.property, createMapMethodOptions(context)),
|
|
28198
|
+
context
|
|
28199
|
+
);
|
|
28200
|
+
}
|
|
28201
|
+
if (isSandboxDate(member.object)) {
|
|
28202
|
+
return evaluateResolvedCallExpression(node, getDateMember(member.property, context.budget, context.compilation?.owner), context, member.object);
|
|
28203
|
+
}
|
|
28204
|
+
if (isFloat32Array(member.object)) {
|
|
28205
|
+
return evaluateResolvedCallExpression(
|
|
28206
|
+
node,
|
|
28207
|
+
getFloat32Member(member.object, member.property, context.budget),
|
|
28208
|
+
context,
|
|
28209
|
+
member.object
|
|
28210
|
+
);
|
|
28211
|
+
}
|
|
28212
|
+
if (isSandboxSet(member.object)) {
|
|
28213
|
+
return evaluatePrimitiveMemberCall(
|
|
28214
|
+
node,
|
|
28215
|
+
"Set",
|
|
28216
|
+
member.property,
|
|
28217
|
+
getSetMember(member.object, member.property, createSetMethodOptions(context)),
|
|
28218
|
+
context
|
|
28219
|
+
);
|
|
28220
|
+
}
|
|
28221
|
+
if (isSandboxGenerator(member.object)) {
|
|
28222
|
+
const memberValue = getGeneratorMember(member.object, member.property, context.budget);
|
|
28223
|
+
if (memberValue === void 0) {
|
|
28224
|
+
throw new TypeError(`Generator#${String(member.property)} is not a supported method.`);
|
|
28225
|
+
}
|
|
28226
|
+
return evaluateResolvedCallExpression(node, memberValue, context, member.object);
|
|
28227
|
+
}
|
|
28228
|
+
if (isSandboxClosure(member.object)) {
|
|
28229
|
+
const memberValue = getClosureMemberValue(member.object, member.property, context);
|
|
28230
|
+
if (memberValue === void 0) {
|
|
28231
|
+
throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
|
|
28232
|
+
}
|
|
28233
|
+
return evaluateResolvedCallExpression(node, memberValue, context, member.object);
|
|
28234
|
+
}
|
|
28235
|
+
if (isSandboxPromise(member.object)) {
|
|
28236
|
+
return evaluateResolvedCallExpression(
|
|
28237
|
+
node,
|
|
28238
|
+
getPromiseMember(member.property, context.budget),
|
|
28239
|
+
context,
|
|
28240
|
+
member.object
|
|
28241
|
+
);
|
|
28242
|
+
}
|
|
28243
|
+
if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
|
|
28244
|
+
return evaluateResolvedCallExpression(
|
|
28245
|
+
node,
|
|
28246
|
+
getRegexMember(member.object, member.property, context.budget),
|
|
28247
|
+
context,
|
|
28248
|
+
member.object
|
|
28249
|
+
);
|
|
28250
|
+
}
|
|
28251
|
+
if (!isIndexableSandboxValue(member.object)) {
|
|
28252
|
+
throw new TypeError("Attempted to read a property from a non-object value.");
|
|
28153
28253
|
}
|
|
28154
|
-
return evaluateResolvedCallExpression(node, memberValue, context, member.object);
|
|
28155
|
-
}
|
|
28156
|
-
if (isSandboxPromise(member.object)) {
|
|
28157
|
-
return evaluateResolvedCallExpression(
|
|
28158
|
-
node,
|
|
28159
|
-
getPromiseMember(member.property, context.budget),
|
|
28160
|
-
context,
|
|
28161
|
-
member.object
|
|
28162
|
-
);
|
|
28163
|
-
}
|
|
28164
|
-
if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
|
|
28165
28254
|
return evaluateResolvedCallExpression(
|
|
28166
28255
|
node,
|
|
28167
|
-
|
|
28256
|
+
getMemberValue(member.object, member.property, context),
|
|
28168
28257
|
context,
|
|
28169
28258
|
member.object
|
|
28170
28259
|
);
|
|
28171
|
-
}
|
|
28172
|
-
if (!isIndexableSandboxValue(member.object)) {
|
|
28173
|
-
throw new TypeError("Attempted to read a property from a non-object value.");
|
|
28174
|
-
}
|
|
28175
|
-
return evaluateResolvedCallExpression(
|
|
28176
|
-
node,
|
|
28177
|
-
getMemberValue(member.object, member.property, context),
|
|
28178
|
-
context,
|
|
28179
|
-
member.object
|
|
28180
|
-
);
|
|
28260
|
+
});
|
|
28181
28261
|
}
|
|
28182
28262
|
function evaluatePrimitiveMemberCall(node, receiverType, property, value, context) {
|
|
28183
28263
|
if (value === void 0) {
|
|
@@ -30678,7 +30758,7 @@ function createMiscGlobals(options) {
|
|
|
30678
30758
|
return {
|
|
30679
30759
|
structuredClone: createSandboxClosure({
|
|
30680
30760
|
sandbox: true,
|
|
30681
|
-
call: ([value]) => structuredCloneSandboxValue(value, options.budget),
|
|
30761
|
+
call: ([value], context) => structuredCloneSandboxValue(value, options.budget, context?.compilation),
|
|
30682
30762
|
name: "structuredClone"
|
|
30683
30763
|
}),
|
|
30684
30764
|
parseInt: createSandboxClosure({
|
|
@@ -30703,11 +30783,20 @@ function createMiscGlobals(options) {
|
|
|
30703
30783
|
})
|
|
30704
30784
|
};
|
|
30705
30785
|
}
|
|
30706
|
-
function structuredCloneSandboxValue(value, budget) {
|
|
30707
|
-
|
|
30708
|
-
const
|
|
30709
|
-
|
|
30710
|
-
|
|
30786
|
+
function structuredCloneSandboxValue(value, budget, parent) {
|
|
30787
|
+
const operation = budget.acquireCompileOwner(false, parent?.owner);
|
|
30788
|
+
const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
|
|
30789
|
+
try {
|
|
30790
|
+
const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
|
|
30791
|
+
assertSandboxGraphDepth(clone);
|
|
30792
|
+
assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
|
|
30793
|
+
allocateProducedSandboxValue(clone, budget);
|
|
30794
|
+
if (compilation !== parent) reconcileCompiledValues(budget, [clone], compilation);
|
|
30795
|
+
return clone;
|
|
30796
|
+
} finally {
|
|
30797
|
+
if (compilation !== parent) compilation.dispose();
|
|
30798
|
+
operation.release();
|
|
30799
|
+
}
|
|
30711
30800
|
}
|
|
30712
30801
|
function assertStructuredCloneable(value, seen) {
|
|
30713
30802
|
if (isSandboxClosure(value) || isSandboxPromise(value) || isSandboxCollectionIterator(value)) {
|
|
@@ -31230,41 +31319,6 @@ function createBuiltinBindings(options) {
|
|
|
31230
31319
|
};
|
|
31231
31320
|
}
|
|
31232
31321
|
|
|
31233
|
-
// packages/safe-js/src/interp/resources.ts
|
|
31234
|
-
import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
|
|
31235
|
-
var runResources = new AsyncLocalStorage5();
|
|
31236
|
-
async function withRunResources(signal, execute) {
|
|
31237
|
-
const controller = new AbortController();
|
|
31238
|
-
const cancel = () => controller.abort(signal?.reason);
|
|
31239
|
-
const cleanups = /* @__PURE__ */ new Set();
|
|
31240
|
-
const resources = {
|
|
31241
|
-
signal: controller.signal,
|
|
31242
|
-
add(close) {
|
|
31243
|
-
cleanups.add(close);
|
|
31244
|
-
}
|
|
31245
|
-
};
|
|
31246
|
-
signal?.addEventListener("abort", cancel, { once: true });
|
|
31247
|
-
if (signal?.aborted) cancel();
|
|
31248
|
-
let result;
|
|
31249
|
-
let failure;
|
|
31250
|
-
let errors = [];
|
|
31251
|
-
try {
|
|
31252
|
-
result = await runResources.run(resources, execute);
|
|
31253
|
-
} catch (error) {
|
|
31254
|
-
failure = { reason: error };
|
|
31255
|
-
} finally {
|
|
31256
|
-
signal?.removeEventListener("abort", cancel);
|
|
31257
|
-
controller.abort(new Error("SafeJS run finished."));
|
|
31258
|
-
const outcomes = await Promise.allSettled(
|
|
31259
|
-
[...cleanups].map((close) => Promise.resolve().then(close))
|
|
31260
|
-
);
|
|
31261
|
-
errors = outcomes.flatMap((outcome) => outcome.status === "rejected" ? [outcome.reason] : []);
|
|
31262
|
-
}
|
|
31263
|
-
if (failure !== void 0) throw failure.reason;
|
|
31264
|
-
if (errors.length > 0) throw new AggregateError(errors, "SafeJS resource cleanup failed.");
|
|
31265
|
-
return result;
|
|
31266
|
-
}
|
|
31267
|
-
|
|
31268
31322
|
// packages/safe-js/src/modules/registry.ts
|
|
31269
31323
|
function createUnknownModuleMessage2(moduleName, moduleNames) {
|
|
31270
31324
|
if (moduleNames.length === 0) {
|
|
@@ -31506,6 +31560,7 @@ var RealmState = class {
|
|
|
31506
31560
|
extensions;
|
|
31507
31561
|
consoleExtension;
|
|
31508
31562
|
cleanups = [];
|
|
31563
|
+
referenceReleases = /* @__PURE__ */ new Set();
|
|
31509
31564
|
callbacks = /* @__PURE__ */ new Map();
|
|
31510
31565
|
pendingCallbacks = /* @__PURE__ */ new Set();
|
|
31511
31566
|
callbackCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -31832,7 +31887,7 @@ var RealmState = class {
|
|
|
31832
31887
|
const pending = withSandboxPromiseRejectionTracker(
|
|
31833
31888
|
this.tracker,
|
|
31834
31889
|
() => runResources.run(
|
|
31835
|
-
{ signal: this.controller.signal, add: this.onCleanup },
|
|
31890
|
+
{ signal: this.controller.signal, referenceReleases: this.referenceReleases, add: this.onCleanup },
|
|
31836
31891
|
() => withCancellationSignal(
|
|
31837
31892
|
this.controller.signal,
|
|
31838
31893
|
() => active && this.phase.getStore()?.active ? runAsyncPrefix(invoke) : this.queue.run(invoke)
|
|
@@ -32027,7 +32082,7 @@ var RealmState = class {
|
|
|
32027
32082
|
() => withSandboxPromiseRejectionTracker(
|
|
32028
32083
|
this.tracker,
|
|
32029
32084
|
() => runResources.run(
|
|
32030
|
-
{ signal: this.controller.signal, add: this.onCleanup },
|
|
32085
|
+
{ signal: this.controller.signal, referenceReleases: this.referenceReleases, add: this.onCleanup },
|
|
32031
32086
|
() => withCancellationSignal(this.controller.signal, task)
|
|
32032
32087
|
)
|
|
32033
32088
|
)
|
|
@@ -32084,6 +32139,8 @@ var RealmState = class {
|
|
|
32084
32139
|
this.hostObjects.clear();
|
|
32085
32140
|
for (const reference of this.guestReferences.keys()) revokeGuestReference(reference, this);
|
|
32086
32141
|
this.guestReferences.clear();
|
|
32142
|
+
for (const release of this.referenceReleases) release();
|
|
32143
|
+
this.referenceReleases.clear();
|
|
32087
32144
|
this.budget.setRetainedValues(this, void 0);
|
|
32088
32145
|
releaseObjectPrototype(this.budget);
|
|
32089
32146
|
this.disposal = (async () => {
|
|
@@ -33337,9 +33394,9 @@ export {
|
|
|
33337
33394
|
validateSnapshotMigration,
|
|
33338
33395
|
restore,
|
|
33339
33396
|
lint,
|
|
33397
|
+
runResources,
|
|
33340
33398
|
declareHostOperation,
|
|
33341
33399
|
createSeededRandom,
|
|
33342
|
-
runResources,
|
|
33343
33400
|
createReplayableRandom,
|
|
33344
33401
|
createRealm,
|
|
33345
33402
|
dump,
|
|
@@ -33349,4 +33406,4 @@ export {
|
|
|
33349
33406
|
FileSnapshotBackend,
|
|
33350
33407
|
run
|
|
33351
33408
|
};
|
|
33352
|
-
//# sourceMappingURL=chunk-
|
|
33409
|
+
//# sourceMappingURL=chunk-DHD453E5.js.map
|