@poe-platform/safe-js 0.1.88 → 0.1.90
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/safe-js/chunks/{chunk-5J6BX3HD.js → chunk-774EXZKX.js} +684 -608
- package/dist/safe-js/chunks/chunk-774EXZKX.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-AD7V4BRD.js → chunk-CHNJPOMA.js} +2 -2
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.js +1 -1
- package/dist/safe-js/index.js +2 -2
- package/dist/safe-js/interp/exceptions.d.ts +1 -0
- package/dist/safe-js/interp/patterns.d.ts +1 -0
- package/package.json +2 -2
- package/dist/safe-js/chunks/chunk-5J6BX3HD.js.map +0 -7
- /package/dist/safe-js/chunks/{chunk-AD7V4BRD.js.map → chunk-CHNJPOMA.js.map} +0 -0
|
@@ -6997,6 +6997,9 @@ function getSandboxPrototype(value, budget) {
|
|
|
6997
6997
|
if (prototypes.has(value)) return prototypes.get(value) ?? null;
|
|
6998
6998
|
return budget !== void 0 && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
|
|
6999
6999
|
}
|
|
7000
|
+
function hasExplicitSandboxPrototype(value) {
|
|
7001
|
+
return prototypes.has(value);
|
|
7002
|
+
}
|
|
7000
7003
|
function setSandboxPrototype(value, prototype, budget) {
|
|
7001
7004
|
if (budget !== void 0 && intrinsicPrototypes.get(budget) === value && prototype !== null) {
|
|
7002
7005
|
throw new TypeError("Object.prototype has an immutable null prototype.");
|
|
@@ -8157,98 +8160,532 @@ function isCounter(value) {
|
|
|
8157
8160
|
// packages/safe-js/src/interp/cancel.ts
|
|
8158
8161
|
import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
|
|
8159
8162
|
|
|
8160
|
-
// packages/safe-js/src/interp/
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8163
|
+
// packages/safe-js/src/interp/regex/engine.ts
|
|
8164
|
+
function matchRegex(pattern, input, lastIndex = 0) {
|
|
8165
|
+
const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
|
|
8166
|
+
return matchRegexFrom(pattern, input, startIndex);
|
|
8167
|
+
}
|
|
8168
|
+
function matchRegexFrom(pattern, input, startIndex) {
|
|
8169
|
+
if (startIndex > input.length) {
|
|
8170
|
+
return null;
|
|
8166
8171
|
}
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8172
|
+
for (let attempt = startIndex; attempt <= input.length; attempt += 1) {
|
|
8173
|
+
const context = { input, flags: pattern.flags, steps: 0 };
|
|
8174
|
+
charge(context);
|
|
8175
|
+
const initialState = {
|
|
8176
|
+
position: attempt,
|
|
8177
|
+
captures: new Array(pattern.captureCount)
|
|
8178
|
+
};
|
|
8179
|
+
const result = matchNode(pattern.body, initialState, context).next();
|
|
8180
|
+
if (!result.done) {
|
|
8181
|
+
return toRegexMatch(input, attempt, result.value);
|
|
8182
|
+
}
|
|
8183
|
+
}
|
|
8184
|
+
return null;
|
|
8174
8185
|
}
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8186
|
+
function* matchNode(node, state, context) {
|
|
8187
|
+
charge(context);
|
|
8188
|
+
switch (node.type) {
|
|
8189
|
+
case "empty":
|
|
8190
|
+
yield state;
|
|
8191
|
+
return;
|
|
8192
|
+
case "literal":
|
|
8193
|
+
if (charactersEqual(context.input[state.position], node.value, context.flags.ignoreCase)) {
|
|
8194
|
+
yield { ...state, position: state.position + 1 };
|
|
8195
|
+
}
|
|
8196
|
+
return;
|
|
8197
|
+
case "dot":
|
|
8198
|
+
if (state.position < context.input.length && (context.flags.dotAll || !isLineTerminator(context.input[state.position]))) {
|
|
8199
|
+
yield { ...state, position: state.position + 1 };
|
|
8200
|
+
}
|
|
8201
|
+
return;
|
|
8202
|
+
case "anchor":
|
|
8203
|
+
if (matchesAnchor(node.kind, state.position, context)) {
|
|
8204
|
+
yield state;
|
|
8205
|
+
}
|
|
8206
|
+
return;
|
|
8207
|
+
case "wordBoundary": {
|
|
8208
|
+
const previousWord = state.position > 0 && isWordCharacter(context.input[state.position - 1]);
|
|
8209
|
+
const nextWord = state.position < context.input.length && isWordCharacter(context.input[state.position]);
|
|
8210
|
+
if (previousWord !== nextWord !== node.negated) {
|
|
8211
|
+
yield state;
|
|
8212
|
+
}
|
|
8213
|
+
return;
|
|
8183
8214
|
}
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8215
|
+
case "characterClass": {
|
|
8216
|
+
const character = context.input[state.position];
|
|
8217
|
+
if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context.flags.ignoreCase)) {
|
|
8218
|
+
yield { ...state, position: state.position + 1 };
|
|
8219
|
+
}
|
|
8220
|
+
return;
|
|
8221
|
+
}
|
|
8222
|
+
case "sequence":
|
|
8223
|
+
yield* matchSequence(node.elements, 0, state, context);
|
|
8224
|
+
return;
|
|
8225
|
+
case "alternation":
|
|
8226
|
+
for (const alternative of node.alternatives) {
|
|
8227
|
+
yield* matchNode(alternative, cloneState(state), context);
|
|
8228
|
+
}
|
|
8229
|
+
return;
|
|
8230
|
+
case "group":
|
|
8231
|
+
for (const result of matchNode(node.body, cloneState(state), context)) {
|
|
8232
|
+
if (!node.capturing || node.index === void 0) {
|
|
8233
|
+
yield result;
|
|
8234
|
+
continue;
|
|
8235
|
+
}
|
|
8236
|
+
const captures = result.captures.slice();
|
|
8237
|
+
captures[node.index - 1] = { start: state.position, end: result.position };
|
|
8238
|
+
yield { position: result.position, captures };
|
|
8239
|
+
}
|
|
8240
|
+
return;
|
|
8241
|
+
case "quantifier":
|
|
8242
|
+
yield* matchQuantifier(node, state, context, 0);
|
|
8190
8243
|
}
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8244
|
+
}
|
|
8245
|
+
function* matchSequence(elements, index, state, context) {
|
|
8246
|
+
charge(context);
|
|
8247
|
+
if (index === elements.length) {
|
|
8248
|
+
yield state;
|
|
8249
|
+
return;
|
|
8194
8250
|
}
|
|
8195
|
-
const
|
|
8196
|
-
context
|
|
8197
|
-
() => evaluateBlockCompletion(node.finalizer, context, evaluateNode2)
|
|
8198
|
-
) : evaluateBlockCompletion(node.finalizer, context, evaluateNode2);
|
|
8199
|
-
const finalizerResult = await (fatalBudgetError === void 0 ? evaluateFinalizer() : withFatalPromiseCleanup(evaluateFinalizer));
|
|
8200
|
-
if (fatalBudgetError !== void 0) {
|
|
8201
|
-
throw fatalBudgetError;
|
|
8251
|
+
for (const result of matchNode(elements[index], state, context)) {
|
|
8252
|
+
yield* matchSequence(elements, index + 1, result, context);
|
|
8202
8253
|
}
|
|
8203
|
-
|
|
8204
|
-
|
|
8254
|
+
}
|
|
8255
|
+
function* matchQuantifier(node, state, context, count) {
|
|
8256
|
+
charge(context);
|
|
8257
|
+
const canRepeat = node.max === void 0 || count < node.max;
|
|
8258
|
+
if (!node.greedy && count >= node.min) {
|
|
8259
|
+
yield state;
|
|
8260
|
+
}
|
|
8261
|
+
if (canRepeat) {
|
|
8262
|
+
for (const result of matchNode(node.body, clearCaptures(node.body, state), context)) {
|
|
8263
|
+
if (result.position === state.position) {
|
|
8264
|
+
if (count >= node.min) {
|
|
8265
|
+
continue;
|
|
8266
|
+
}
|
|
8267
|
+
if (count + 1 >= node.min) {
|
|
8268
|
+
yield result;
|
|
8269
|
+
} else {
|
|
8270
|
+
yield* matchQuantifier(node, result, context, count + 1);
|
|
8271
|
+
}
|
|
8272
|
+
continue;
|
|
8273
|
+
}
|
|
8274
|
+
yield* matchQuantifier(node, result, context, count + 1);
|
|
8275
|
+
}
|
|
8276
|
+
}
|
|
8277
|
+
if (node.greedy && count >= node.min) {
|
|
8278
|
+
yield state;
|
|
8205
8279
|
}
|
|
8206
|
-
return finalizerResult;
|
|
8207
8280
|
}
|
|
8208
|
-
function
|
|
8281
|
+
function matchesAnchor(kind, position, context) {
|
|
8282
|
+
if (kind === "start") {
|
|
8283
|
+
return position === 0 || context.flags.multiline && position > 0 && isLineTerminator(context.input[position - 1]);
|
|
8284
|
+
}
|
|
8285
|
+
return position === context.input.length || context.flags.multiline && position < context.input.length && isLineTerminator(context.input[position]);
|
|
8286
|
+
}
|
|
8287
|
+
function matchesCharacterClass(character, items, negated, ignoreCase) {
|
|
8288
|
+
const matched = items.some((item) => matchesCharacterClassItem(character, item, ignoreCase));
|
|
8289
|
+
return negated ? !matched : matched;
|
|
8290
|
+
}
|
|
8291
|
+
function matchesCharacterClassItem(character, item, ignoreCase) {
|
|
8292
|
+
if (item.type === "character") {
|
|
8293
|
+
return charactersEqual(character, item.value, ignoreCase);
|
|
8294
|
+
}
|
|
8295
|
+
if (item.type === "range") {
|
|
8296
|
+
const candidate = character.charCodeAt(0);
|
|
8297
|
+
const from = item.from.charCodeAt(0);
|
|
8298
|
+
const to = item.to.charCodeAt(0);
|
|
8299
|
+
if (candidate >= from && candidate <= to) {
|
|
8300
|
+
return true;
|
|
8301
|
+
}
|
|
8302
|
+
if (!ignoreCase) {
|
|
8303
|
+
return false;
|
|
8304
|
+
}
|
|
8305
|
+
const foldedCandidate = foldCharacter(character, true).charCodeAt(0);
|
|
8306
|
+
const foldedFrom = foldCharacter(item.from, true).charCodeAt(0);
|
|
8307
|
+
const foldedTo = foldCharacter(item.to, true).charCodeAt(0);
|
|
8308
|
+
return foldedCandidate >= foldedFrom && foldedCandidate <= foldedTo;
|
|
8309
|
+
}
|
|
8310
|
+
const matched = item.kind === "digit" ? isDigit(character) : item.kind === "word" ? isWordCharacter(character) : isSpaceCharacter(character);
|
|
8311
|
+
return item.negated ? !matched : matched;
|
|
8312
|
+
}
|
|
8313
|
+
function toRegexMatch(input, start, state) {
|
|
8209
8314
|
return {
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8315
|
+
index: start,
|
|
8316
|
+
text: input.slice(start, state.position),
|
|
8317
|
+
captures: state.captures.map(
|
|
8318
|
+
(capture) => capture === void 0 ? void 0 : input.slice(capture.start, capture.end)
|
|
8319
|
+
)
|
|
8214
8320
|
};
|
|
8215
8321
|
}
|
|
8216
|
-
function
|
|
8217
|
-
return
|
|
8322
|
+
function cloneState(state) {
|
|
8323
|
+
return { position: state.position, captures: state.captures.slice() };
|
|
8218
8324
|
}
|
|
8219
|
-
function
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
}
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8325
|
+
function clearCaptures(node, state) {
|
|
8326
|
+
const captures = state.captures.slice();
|
|
8327
|
+
clearNodeCaptures(node, captures);
|
|
8328
|
+
return { position: state.position, captures };
|
|
8329
|
+
}
|
|
8330
|
+
function clearNodeCaptures(node, captures) {
|
|
8331
|
+
if (node.type === "group") {
|
|
8332
|
+
if (node.capturing && node.index !== void 0) {
|
|
8333
|
+
captures[node.index - 1] = void 0;
|
|
8334
|
+
}
|
|
8335
|
+
clearNodeCaptures(node.body, captures);
|
|
8336
|
+
return;
|
|
8226
8337
|
}
|
|
8227
|
-
if (
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
});
|
|
8338
|
+
if (node.type === "sequence") {
|
|
8339
|
+
for (const element of node.elements) {
|
|
8340
|
+
clearNodeCaptures(element, captures);
|
|
8341
|
+
}
|
|
8342
|
+
return;
|
|
8233
8343
|
}
|
|
8234
|
-
if (
|
|
8235
|
-
|
|
8344
|
+
if (node.type === "alternation") {
|
|
8345
|
+
for (const alternative of node.alternatives) {
|
|
8346
|
+
clearNodeCaptures(alternative, captures);
|
|
8347
|
+
}
|
|
8348
|
+
return;
|
|
8236
8349
|
}
|
|
8237
|
-
if (
|
|
8238
|
-
|
|
8239
|
-
chargeBudget: false,
|
|
8240
|
-
cause: readErrorCause(reason),
|
|
8241
|
-
span
|
|
8242
|
-
});
|
|
8350
|
+
if (node.type === "quantifier") {
|
|
8351
|
+
clearNodeCaptures(node.body, captures);
|
|
8243
8352
|
}
|
|
8244
|
-
return deepCopyToSandbox(reason);
|
|
8245
8353
|
}
|
|
8246
|
-
function
|
|
8247
|
-
|
|
8248
|
-
|
|
8354
|
+
function charge(context) {
|
|
8355
|
+
context.steps += 1;
|
|
8356
|
+
allocateRegexSteps(context.steps);
|
|
8357
|
+
}
|
|
8358
|
+
function normalizeLastIndex(lastIndex) {
|
|
8359
|
+
if (!Number.isFinite(lastIndex) || lastIndex <= 0) {
|
|
8360
|
+
return 0;
|
|
8249
8361
|
}
|
|
8250
|
-
|
|
8251
|
-
|
|
8362
|
+
return Math.floor(lastIndex);
|
|
8363
|
+
}
|
|
8364
|
+
function charactersEqual(left, right, ignoreCase) {
|
|
8365
|
+
return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
|
|
8366
|
+
}
|
|
8367
|
+
function foldCharacter(character, ignoreCase) {
|
|
8368
|
+
if (!ignoreCase) {
|
|
8369
|
+
return character;
|
|
8370
|
+
}
|
|
8371
|
+
const folded = character.toUpperCase();
|
|
8372
|
+
if (folded.length !== 1) {
|
|
8373
|
+
return character;
|
|
8374
|
+
}
|
|
8375
|
+
if (character.charCodeAt(0) >= 128 && folded.charCodeAt(0) < 128) {
|
|
8376
|
+
return character;
|
|
8377
|
+
}
|
|
8378
|
+
return folded;
|
|
8379
|
+
}
|
|
8380
|
+
function isDigit(character) {
|
|
8381
|
+
return character >= "0" && character <= "9";
|
|
8382
|
+
}
|
|
8383
|
+
function isWordCharacter(character) {
|
|
8384
|
+
return isDigit(character) || character >= "A" && character <= "Z" || character >= "a" && character <= "z" || character === "_";
|
|
8385
|
+
}
|
|
8386
|
+
function isSpaceCharacter(character) {
|
|
8387
|
+
return character === " " || character === "\f" || character === "\n" || character === "\r" || character === " " || character === "\v" || character === "\xA0" || character === "\u1680" || character >= "\u2000" && character <= "\u200A" || character === "\u2028" || character === "\u2029" || character === "\u202F" || character === "\u205F" || character === "\u3000" || character === "\uFEFF";
|
|
8388
|
+
}
|
|
8389
|
+
function isLineTerminator(character) {
|
|
8390
|
+
return character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029";
|
|
8391
|
+
}
|
|
8392
|
+
|
|
8393
|
+
// packages/safe-js/src/interp/methods/regex.ts
|
|
8394
|
+
var regexMethodNames = /* @__PURE__ */ new Set(["exec", "test"]);
|
|
8395
|
+
function isRegexMethodName(property) {
|
|
8396
|
+
return typeof property === "string" && regexMethodNames.has(property);
|
|
8397
|
+
}
|
|
8398
|
+
function getRegexMember(target, property, budget) {
|
|
8399
|
+
if (property === "source") return escapeRegexSource(target.source, budget);
|
|
8400
|
+
if (property === "flags") {
|
|
8401
|
+
const flags = [..."gims"].filter((flag) => target.flags.includes(flag)).join("");
|
|
8402
|
+
return budget === void 0 ? flags : budget.allocateString(flags);
|
|
8403
|
+
}
|
|
8404
|
+
if (property === "lastIndex") return target.lastIndex;
|
|
8405
|
+
if (!isRegexMethodName(property)) {
|
|
8406
|
+
return void 0;
|
|
8407
|
+
}
|
|
8408
|
+
return createSandboxClosure({
|
|
8409
|
+
sandbox: true,
|
|
8410
|
+
name: `RegExp#${property}`,
|
|
8411
|
+
call: (args) => callRegexMethod(target, property, args)
|
|
8412
|
+
});
|
|
8413
|
+
}
|
|
8414
|
+
function escapeRegexSource(source, budget) {
|
|
8415
|
+
let text = "";
|
|
8416
|
+
let escaped = false;
|
|
8417
|
+
let inClass = false;
|
|
8418
|
+
for (const character of source) {
|
|
8419
|
+
budget?.visitNode();
|
|
8420
|
+
if (character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029") {
|
|
8421
|
+
if (escaped) text = text.slice(0, -1);
|
|
8422
|
+
text += character === "\n" ? "\\n" : character === "\r" ? "\\r" : character === "\u2028" ? "\\u2028" : "\\u2029";
|
|
8423
|
+
escaped = false;
|
|
8424
|
+
} else {
|
|
8425
|
+
if (!escaped && character === "[") inClass = true;
|
|
8426
|
+
if (!escaped && character === "]") inClass = false;
|
|
8427
|
+
text += character === "/" && !escaped && !inClass ? "\\/" : character;
|
|
8428
|
+
escaped = character === "\\" && !escaped;
|
|
8429
|
+
}
|
|
8430
|
+
budget?.allocateString(text);
|
|
8431
|
+
}
|
|
8432
|
+
text = text === "" ? "(?:)" : text;
|
|
8433
|
+
return budget === void 0 ? text : budget.allocateString(text);
|
|
8434
|
+
}
|
|
8435
|
+
function setRegexMember(target, property, value) {
|
|
8436
|
+
if (property !== "lastIndex") {
|
|
8437
|
+
throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
8438
|
+
}
|
|
8439
|
+
target.lastIndex = Number(value);
|
|
8440
|
+
}
|
|
8441
|
+
function callRegexMethod(target, methodName, args) {
|
|
8442
|
+
const match = executeRegex(target, String(args[0]));
|
|
8443
|
+
return methodName === "test" ? match !== null : toMatchArray(match, String(args[0]));
|
|
8444
|
+
}
|
|
8445
|
+
function executeRegex(target, input) {
|
|
8446
|
+
const pattern = getSandboxRegexPattern(target);
|
|
8447
|
+
const match = matchRegex(pattern, input, target.lastIndex);
|
|
8448
|
+
if (pattern.flags.global) {
|
|
8449
|
+
target.lastIndex = match === null ? 0 : match.index + match.text.length;
|
|
8450
|
+
}
|
|
8451
|
+
return match;
|
|
8452
|
+
}
|
|
8453
|
+
function toMatchArray(match, input) {
|
|
8454
|
+
if (match === null) {
|
|
8455
|
+
return null;
|
|
8456
|
+
}
|
|
8457
|
+
const result = [match.text, ...match.captures];
|
|
8458
|
+
Object.assign(result, { index: match.index, input, groups: void 0 });
|
|
8459
|
+
return result;
|
|
8460
|
+
}
|
|
8461
|
+
|
|
8462
|
+
// packages/safe-js/src/interp/string-coercion.ts
|
|
8463
|
+
var defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
|
|
8464
|
+
function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
|
|
8465
|
+
if (value === null || typeof value !== "object") {
|
|
8466
|
+
if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
|
|
8467
|
+
return budget.allocateString(String(value));
|
|
8468
|
+
}
|
|
8469
|
+
const invocation = context?.invokeClosure !== void 0 ? context : {
|
|
8470
|
+
...context,
|
|
8471
|
+
stack: context?.stack ?? [],
|
|
8472
|
+
thisValue: context?.thisValue,
|
|
8473
|
+
invokeClosure: async (closure, args, thisValue) => {
|
|
8474
|
+
const leaveCall = budget.enterCall();
|
|
8475
|
+
try {
|
|
8476
|
+
const result = closure.call(args, { ...invocation, thisValue });
|
|
8477
|
+
if (isSandboxPromise(result)) {
|
|
8478
|
+
await result.synchronousPrefix;
|
|
8479
|
+
return result;
|
|
8480
|
+
}
|
|
8481
|
+
return await result;
|
|
8482
|
+
} finally {
|
|
8483
|
+
leaveCall();
|
|
8484
|
+
}
|
|
8485
|
+
}
|
|
8486
|
+
};
|
|
8487
|
+
return stringifyObject(value, budget, invocation, joining);
|
|
8488
|
+
}
|
|
8489
|
+
async function stringifyObject(value, budget, context, joining) {
|
|
8490
|
+
const leaveCall = budget.enterCall();
|
|
8491
|
+
try {
|
|
8492
|
+
budget.visitNode();
|
|
8493
|
+
for (const name of ["toString", "valueOf"]) {
|
|
8494
|
+
const hook = conversionHook(value, name, budget);
|
|
8495
|
+
let result;
|
|
8496
|
+
if (hook === defaultStringHook) {
|
|
8497
|
+
result = await defaultToString(value, budget, context, joining);
|
|
8498
|
+
} else {
|
|
8499
|
+
if (!isSandboxClosure(hook)) continue;
|
|
8500
|
+
if (context?.invokeClosure === void 0) {
|
|
8501
|
+
throw new TypeError("String hooks require a sandbox call context.");
|
|
8502
|
+
}
|
|
8503
|
+
result = await context.invokeClosure(hook, [], value);
|
|
8504
|
+
}
|
|
8505
|
+
if (result === null || typeof result !== "object") {
|
|
8506
|
+
return sandboxString(result, budget, context, joining);
|
|
8507
|
+
}
|
|
8508
|
+
}
|
|
8509
|
+
throw new TypeError("Cannot convert object to primitive value");
|
|
8510
|
+
} finally {
|
|
8511
|
+
leaveCall();
|
|
8512
|
+
}
|
|
8513
|
+
}
|
|
8514
|
+
function conversionHook(value, name, budget) {
|
|
8515
|
+
const implicitBuiltin = !hasExplicitSandboxPrototype(value) && (Array.isArray(value) || isSandboxDate(value) || isFloat32Array(value) || sandboxErrorTypes.has(value) || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxGenerator(value) || isGuestHostObject(value));
|
|
8516
|
+
let current = value;
|
|
8517
|
+
let depth = 0;
|
|
8518
|
+
while (current !== null) {
|
|
8519
|
+
const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
|
|
8520
|
+
const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, name);
|
|
8521
|
+
if (descriptor !== void 0) {
|
|
8522
|
+
if (!Object.hasOwn(descriptor, "value"))
|
|
8523
|
+
throw new TypeError("String conversion requires sandbox data properties.");
|
|
8524
|
+
return descriptor.value;
|
|
8525
|
+
}
|
|
8526
|
+
const parent = getSandboxPrototype(current, budget);
|
|
8527
|
+
if (current === value && (implicitBuiltin || parent === null && !hasExplicitSandboxPrototype(value))) {
|
|
8528
|
+
return name === "toString" ? defaultStringHook : void 0;
|
|
8529
|
+
}
|
|
8530
|
+
current = parent;
|
|
8531
|
+
if (current !== null) {
|
|
8532
|
+
budget.visitNode();
|
|
8533
|
+
assertSandboxDataDepth(++depth);
|
|
8534
|
+
}
|
|
8535
|
+
}
|
|
8536
|
+
return void 0;
|
|
8537
|
+
}
|
|
8538
|
+
async function defaultToString(value, budget, context, joining) {
|
|
8539
|
+
if (isSandboxMap(value)) return "[object Map]";
|
|
8540
|
+
if (isSandboxSet(value)) return "[object Set]";
|
|
8541
|
+
if (isSandboxGenerator(value)) return "[object Generator]";
|
|
8542
|
+
if (isSandboxRegex(value)) {
|
|
8543
|
+
return budget.allocateString(
|
|
8544
|
+
`/${getRegexMember(value, "source", budget)}/${getRegexMember(value, "flags", budget)}`
|
|
8545
|
+
);
|
|
8546
|
+
}
|
|
8547
|
+
if (isSandboxDate(value)) return budget.allocateString(dateString(value));
|
|
8548
|
+
if (Array.isArray(value) || isFloat32Array(value)) {
|
|
8549
|
+
if (Object.hasOwn(value, "join")) {
|
|
8550
|
+
const join = ownDataValue(value, "join");
|
|
8551
|
+
if (!isSandboxClosure(join))
|
|
8552
|
+
return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
|
|
8553
|
+
if (context?.invokeClosure === void 0) {
|
|
8554
|
+
throw new TypeError("String hooks require a sandbox call context.");
|
|
8555
|
+
}
|
|
8556
|
+
return context.invokeClosure(join, [], value);
|
|
8557
|
+
}
|
|
8558
|
+
if (joining.has(value)) return "";
|
|
8559
|
+
joining.add(value);
|
|
8560
|
+
try {
|
|
8561
|
+
const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
|
|
8562
|
+
let text = "";
|
|
8563
|
+
for (let index = 0; index < length; index++) {
|
|
8564
|
+
budget.visitNode();
|
|
8565
|
+
const element = ownDataValue(value, String(index));
|
|
8566
|
+
const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
|
|
8567
|
+
text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
|
|
8568
|
+
}
|
|
8569
|
+
return text;
|
|
8570
|
+
} finally {
|
|
8571
|
+
joining.delete(value);
|
|
8572
|
+
}
|
|
8573
|
+
}
|
|
8574
|
+
if (sandboxErrorTypes.has(value)) {
|
|
8575
|
+
const nameValue = ownDataValue(value, "name");
|
|
8576
|
+
const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
|
|
8577
|
+
const messageValue = ownDataValue(value, "message");
|
|
8578
|
+
const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
|
|
8579
|
+
return name === "" ? message : message === "" ? name : `${name}: ${message}`;
|
|
8580
|
+
}
|
|
8581
|
+
return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
|
|
8582
|
+
}
|
|
8583
|
+
function ownDataValue(value, name) {
|
|
8584
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, name);
|
|
8585
|
+
if (descriptor !== void 0 && !Object.hasOwn(descriptor, "value")) {
|
|
8586
|
+
throw new TypeError("String conversion requires sandbox data properties.");
|
|
8587
|
+
}
|
|
8588
|
+
return descriptor?.value;
|
|
8589
|
+
}
|
|
8590
|
+
|
|
8591
|
+
// packages/safe-js/src/interp/property-key.ts
|
|
8592
|
+
async function toPropertyKey(value, budget, context) {
|
|
8593
|
+
if (typeof value === "string") return value;
|
|
8594
|
+
return sandboxString(value, budget, context);
|
|
8595
|
+
}
|
|
8596
|
+
|
|
8597
|
+
// packages/safe-js/src/interp/exceptions.ts
|
|
8598
|
+
var capturedExceptionBrand = /* @__PURE__ */ Symbol("CapturedException");
|
|
8599
|
+
async function evaluateThrowStatement(node, context, evaluateNode2) {
|
|
8600
|
+
const argument = await evaluateNode2(node.argument, context);
|
|
8601
|
+
if (argument.kind !== "normal") {
|
|
8602
|
+
return argument;
|
|
8603
|
+
}
|
|
8604
|
+
return {
|
|
8605
|
+
kind: "throw",
|
|
8606
|
+
hasValue: true,
|
|
8607
|
+
span: node.span,
|
|
8608
|
+
stackFrames: context.callStack,
|
|
8609
|
+
value: argument.value
|
|
8610
|
+
};
|
|
8611
|
+
}
|
|
8612
|
+
async function evaluateTryStatement(node, context, evaluateNode2) {
|
|
8613
|
+
let fatalBudgetError;
|
|
8614
|
+
let tryResult;
|
|
8615
|
+
try {
|
|
8616
|
+
tryResult = await evaluateBlockCompletion(node.block, context, evaluateNode2);
|
|
8617
|
+
} catch (error) {
|
|
8618
|
+
if (!isBudgetExceeded(error) || node.finalizer === void 0) {
|
|
8619
|
+
throw error;
|
|
8620
|
+
}
|
|
8621
|
+
fatalBudgetError = error;
|
|
8622
|
+
tryResult = {
|
|
8623
|
+
kind: "throw",
|
|
8624
|
+
hasValue: true,
|
|
8625
|
+
value: void 0
|
|
8626
|
+
};
|
|
8627
|
+
}
|
|
8628
|
+
const tryOrCatchResult = fatalBudgetError === void 0 && tryResult.kind === "throw" && node.handler !== void 0 ? await evaluateCatchClause(node.handler, tryResult.value, context, evaluateNode2) : tryResult;
|
|
8629
|
+
if (node.finalizer === void 0 || tryOrCatchResult.kind === "error") {
|
|
8630
|
+
return tryOrCatchResult;
|
|
8631
|
+
}
|
|
8632
|
+
const evaluateFinalizer = () => fatalBudgetError?.budget === "deadline" ? evaluateWithoutDeadlineChecks(
|
|
8633
|
+
context,
|
|
8634
|
+
() => evaluateBlockCompletion(node.finalizer, context, evaluateNode2)
|
|
8635
|
+
) : evaluateBlockCompletion(node.finalizer, context, evaluateNode2);
|
|
8636
|
+
const finalizerResult = await (fatalBudgetError === void 0 ? evaluateFinalizer() : withFatalPromiseCleanup(evaluateFinalizer));
|
|
8637
|
+
if (fatalBudgetError !== void 0) {
|
|
8638
|
+
throw fatalBudgetError;
|
|
8639
|
+
}
|
|
8640
|
+
if (finalizerResult.kind === "normal") {
|
|
8641
|
+
return tryOrCatchResult;
|
|
8642
|
+
}
|
|
8643
|
+
return finalizerResult;
|
|
8644
|
+
}
|
|
8645
|
+
function createCapturedException(reason, stackFrames, sandbox = false) {
|
|
8646
|
+
return {
|
|
8647
|
+
reason,
|
|
8648
|
+
sandbox,
|
|
8649
|
+
stackFrames,
|
|
8650
|
+
[capturedExceptionBrand]: true
|
|
8651
|
+
};
|
|
8652
|
+
}
|
|
8653
|
+
function isCapturedException(value) {
|
|
8654
|
+
return typeof value === "object" && value !== null && capturedExceptionBrand in value;
|
|
8655
|
+
}
|
|
8656
|
+
function coerceThrownValue(reason, budget, stackFrames, span, sandbox = false) {
|
|
8657
|
+
if (reason instanceof HostCallResumabilityError) {
|
|
8658
|
+
throw reason;
|
|
8659
|
+
}
|
|
8660
|
+
if (isSubsetErrorValue(reason)) {
|
|
8661
|
+
attachErrorSpan(reason, readErrorSpan(reason) ?? span);
|
|
8662
|
+
return reason;
|
|
8663
|
+
}
|
|
8664
|
+
if (reason instanceof Error) {
|
|
8665
|
+
return createSubsetErrorValue(reason.name || "Error", reason.message, stackFrames, budget, {
|
|
8666
|
+
chargeBudget: false,
|
|
8667
|
+
cause: readErrorCause(reason),
|
|
8668
|
+
span
|
|
8669
|
+
});
|
|
8670
|
+
}
|
|
8671
|
+
if (sandbox) {
|
|
8672
|
+
return reason;
|
|
8673
|
+
}
|
|
8674
|
+
if (isErrorLikeValue(reason)) {
|
|
8675
|
+
return createSubsetErrorValue(reason.name || "Error", reason.message, stackFrames, budget, {
|
|
8676
|
+
chargeBudget: false,
|
|
8677
|
+
cause: readErrorCause(reason),
|
|
8678
|
+
span
|
|
8679
|
+
});
|
|
8680
|
+
}
|
|
8681
|
+
return deepCopyToSandbox(reason);
|
|
8682
|
+
}
|
|
8683
|
+
function surfaceThrownValue(reason, budget, stackFrames = [], span) {
|
|
8684
|
+
if (reason instanceof HostCallResumabilityError) {
|
|
8685
|
+
throw reason;
|
|
8686
|
+
}
|
|
8687
|
+
if (isSubsetErrorValue(reason)) {
|
|
8688
|
+
normalizeSurfacedSubsetError(reason, budget, stackFrames, span);
|
|
8252
8689
|
return reason;
|
|
8253
8690
|
}
|
|
8254
8691
|
if (reason instanceof Error) {
|
|
@@ -8547,12 +8984,13 @@ async function resolvePatternPropertyKey(property, context, evaluateNode2) {
|
|
|
8547
8984
|
result: computedKey
|
|
8548
8985
|
};
|
|
8549
8986
|
}
|
|
8550
|
-
if (typeof computedKey.value !== "string" && typeof computedKey.value !== "number") {
|
|
8551
|
-
throw new TypeError("Computed catch binding keys must evaluate to a string or number.");
|
|
8552
|
-
}
|
|
8553
8987
|
return {
|
|
8554
8988
|
ok: true,
|
|
8555
|
-
value: computedKey.value
|
|
8989
|
+
value: await (context.toPropertyKey?.(computedKey.value) ?? toPropertyKey(
|
|
8990
|
+
computedKey.value,
|
|
8991
|
+
context.budget,
|
|
8992
|
+
{ stack: context.callStack, thisValue: void 0 }
|
|
8993
|
+
))
|
|
8556
8994
|
};
|
|
8557
8995
|
}
|
|
8558
8996
|
function getStaticPropertyKey(property) {
|
|
@@ -23089,17 +23527,17 @@ async function bindMemberExpression(pattern, value, scope, context) {
|
|
|
23089
23527
|
if (object.kind !== "normal") {
|
|
23090
23528
|
return { ok: false, result: object };
|
|
23091
23529
|
}
|
|
23530
|
+
const property = pattern.computed ? await context.evaluate(pattern.property) : { kind: "normal", value: getStaticPropertyName(pattern.property) };
|
|
23531
|
+
if (property.kind !== "normal") {
|
|
23532
|
+
return { ok: false, result: property };
|
|
23533
|
+
}
|
|
23092
23534
|
if (object.value === null || object.value === void 0) {
|
|
23093
23535
|
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
23094
23536
|
}
|
|
23095
23537
|
if (!isIndexableValue(object.value)) {
|
|
23096
23538
|
throw new TypeError("Assignment expressions require a sandbox object property.");
|
|
23097
23539
|
}
|
|
23098
|
-
|
|
23099
|
-
if (!property.ok) {
|
|
23100
|
-
return property;
|
|
23101
|
-
}
|
|
23102
|
-
context.setProperty(object.value, property.value, value);
|
|
23540
|
+
context.setProperty(object.value, await context.toPropertyKey(property.value), value);
|
|
23103
23541
|
return { ok: true };
|
|
23104
23542
|
}
|
|
23105
23543
|
async function evaluatePatternKey(property, context) {
|
|
@@ -23110,10 +23548,7 @@ async function evaluateProperty(property, context) {
|
|
|
23110
23548
|
if (result.kind !== "normal") {
|
|
23111
23549
|
return { ok: false, result };
|
|
23112
23550
|
}
|
|
23113
|
-
|
|
23114
|
-
throw new TypeError("Computed property access requires a string or number key.");
|
|
23115
|
-
}
|
|
23116
|
-
return { ok: true, value: result.value };
|
|
23551
|
+
return { ok: true, value: await context.toPropertyKey(result.value) };
|
|
23117
23552
|
}
|
|
23118
23553
|
function getStaticPropertyName(property) {
|
|
23119
23554
|
if (property.type === "Identifier") {
|
|
@@ -23153,116 +23588,36 @@ function describeRuntimeValue(value) {
|
|
|
23153
23588
|
if (typeof value === "object") return value.constructor?.name ?? "Object";
|
|
23154
23589
|
return typeof value;
|
|
23155
23590
|
}
|
|
23156
|
-
function copyObjectRestValue(value, excludedKeys) {
|
|
23157
|
-
const rest = /* @__PURE__ */ Object.create(null);
|
|
23158
|
-
for (const [key, entryValue] of ownEnumerableSandboxEntries(value)) {
|
|
23159
|
-
if (!excludedKeys.has(key)) {
|
|
23160
|
-
defineProperty(rest, key, entryValue);
|
|
23161
|
-
}
|
|
23162
|
-
}
|
|
23163
|
-
return rest;
|
|
23164
|
-
}
|
|
23165
|
-
function isIndexableValue(value) {
|
|
23166
|
-
return typeof value === "object" && value !== null;
|
|
23167
|
-
}
|
|
23168
|
-
function defineProperty(target, key, value) {
|
|
23169
|
-
Object.defineProperty(target, key, {
|
|
23170
|
-
configurable: true,
|
|
23171
|
-
enumerable: true,
|
|
23172
|
-
value,
|
|
23173
|
-
writable: true
|
|
23174
|
-
});
|
|
23175
|
-
}
|
|
23176
|
-
|
|
23177
|
-
// packages/safe-js/src/interp/var-hoist.ts
|
|
23178
|
-
function hoistVarDeclarations(node, scope) {
|
|
23179
|
-
for (const declaration of hoistedVarDeclarations([node])) {
|
|
23180
|
-
for (const declarator of declaration.declarations) {
|
|
23181
|
-
for (const identifier of boundIdentifiers(declarator.id)) {
|
|
23182
|
-
scope.declareVar(identifier.name);
|
|
23183
|
-
}
|
|
23184
|
-
}
|
|
23185
|
-
}
|
|
23186
|
-
}
|
|
23187
|
-
|
|
23188
|
-
// packages/safe-js/src/interp/string-coercion.ts
|
|
23189
|
-
function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
|
|
23190
|
-
if (value === null || typeof value !== "object") {
|
|
23191
|
-
if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
|
|
23192
|
-
return budget.allocateString(String(value));
|
|
23193
|
-
}
|
|
23194
|
-
return stringifyObject(value, budget, context, joining);
|
|
23195
|
-
}
|
|
23196
|
-
async function stringifyObject(value, budget, context, joining) {
|
|
23197
|
-
const leaveCall = budget.enterCall();
|
|
23198
|
-
try {
|
|
23199
|
-
budget.visitNode();
|
|
23200
|
-
for (const name of ["toString", "valueOf"]) {
|
|
23201
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, name);
|
|
23202
|
-
let result;
|
|
23203
|
-
if (descriptor === void 0) {
|
|
23204
|
-
if (name === "valueOf") continue;
|
|
23205
|
-
result = await defaultToString(value, budget, context, joining);
|
|
23206
|
-
} else {
|
|
23207
|
-
const hook = ownDataValue(value, name);
|
|
23208
|
-
if (!isSandboxClosure(hook)) continue;
|
|
23209
|
-
if (context?.invokeClosure === void 0) {
|
|
23210
|
-
throw new TypeError("String hooks require a sandbox call context.");
|
|
23211
|
-
}
|
|
23212
|
-
result = await context.invokeClosure(hook, [], value);
|
|
23213
|
-
}
|
|
23214
|
-
if (result === null || typeof result !== "object") {
|
|
23215
|
-
return sandboxString(result, budget, context, joining);
|
|
23216
|
-
}
|
|
23217
|
-
}
|
|
23218
|
-
throw new TypeError("Cannot convert object to primitive value");
|
|
23219
|
-
} finally {
|
|
23220
|
-
leaveCall();
|
|
23221
|
-
}
|
|
23222
|
-
}
|
|
23223
|
-
async function defaultToString(value, budget, context, joining) {
|
|
23224
|
-
if (isSandboxDate(value)) return budget.allocateString(dateString(value));
|
|
23225
|
-
if (Array.isArray(value) || isFloat32Array(value)) {
|
|
23226
|
-
if (Object.hasOwn(value, "join")) {
|
|
23227
|
-
const join = ownDataValue(value, "join");
|
|
23228
|
-
if (!isSandboxClosure(join))
|
|
23229
|
-
return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
|
|
23230
|
-
if (context?.invokeClosure === void 0) {
|
|
23231
|
-
throw new TypeError("String hooks require a sandbox call context.");
|
|
23232
|
-
}
|
|
23233
|
-
return context.invokeClosure(join, [], value);
|
|
23234
|
-
}
|
|
23235
|
-
if (joining.has(value)) return "";
|
|
23236
|
-
joining.add(value);
|
|
23237
|
-
try {
|
|
23238
|
-
const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
|
|
23239
|
-
let text = "";
|
|
23240
|
-
for (let index = 0; index < length; index++) {
|
|
23241
|
-
budget.visitNode();
|
|
23242
|
-
const element = ownDataValue(value, String(index));
|
|
23243
|
-
const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
|
|
23244
|
-
text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
|
|
23245
|
-
}
|
|
23246
|
-
return text;
|
|
23247
|
-
} finally {
|
|
23248
|
-
joining.delete(value);
|
|
23591
|
+
function copyObjectRestValue(value, excludedKeys) {
|
|
23592
|
+
const rest = /* @__PURE__ */ Object.create(null);
|
|
23593
|
+
for (const [key, entryValue] of ownEnumerableSandboxEntries(value)) {
|
|
23594
|
+
if (!excludedKeys.has(key)) {
|
|
23595
|
+
defineProperty(rest, key, entryValue);
|
|
23249
23596
|
}
|
|
23250
23597
|
}
|
|
23251
|
-
|
|
23252
|
-
const nameValue = ownDataValue(value, "name");
|
|
23253
|
-
const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
|
|
23254
|
-
const messageValue = ownDataValue(value, "message");
|
|
23255
|
-
const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
|
|
23256
|
-
return name === "" ? message : message === "" ? name : `${name}: ${message}`;
|
|
23257
|
-
}
|
|
23258
|
-
return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
|
|
23598
|
+
return rest;
|
|
23259
23599
|
}
|
|
23260
|
-
function
|
|
23261
|
-
|
|
23262
|
-
|
|
23263
|
-
|
|
23600
|
+
function isIndexableValue(value) {
|
|
23601
|
+
return typeof value === "object" && value !== null;
|
|
23602
|
+
}
|
|
23603
|
+
function defineProperty(target, key, value) {
|
|
23604
|
+
Object.defineProperty(target, key, {
|
|
23605
|
+
configurable: true,
|
|
23606
|
+
enumerable: true,
|
|
23607
|
+
value,
|
|
23608
|
+
writable: true
|
|
23609
|
+
});
|
|
23610
|
+
}
|
|
23611
|
+
|
|
23612
|
+
// packages/safe-js/src/interp/var-hoist.ts
|
|
23613
|
+
function hoistVarDeclarations(node, scope) {
|
|
23614
|
+
for (const declaration of hoistedVarDeclarations([node])) {
|
|
23615
|
+
for (const declarator of declaration.declarations) {
|
|
23616
|
+
for (const identifier of boundIdentifiers(declarator.id)) {
|
|
23617
|
+
scope.declareVar(identifier.name);
|
|
23618
|
+
}
|
|
23619
|
+
}
|
|
23264
23620
|
}
|
|
23265
|
-
return descriptor?.value;
|
|
23266
23621
|
}
|
|
23267
23622
|
|
|
23268
23623
|
// packages/safe-js/src/interp/methods/array.ts
|
|
@@ -24145,387 +24500,112 @@ async function callMapMethod(target, methodName, args, options, stack = []) {
|
|
|
24145
24500
|
const value = target.entries.get(key);
|
|
24146
24501
|
await options.callClosure(callback, [value, key, target], stack, args[1]);
|
|
24147
24502
|
}
|
|
24148
|
-
} finally {
|
|
24149
|
-
cursor.leave();
|
|
24150
|
-
}
|
|
24151
|
-
return void 0;
|
|
24152
|
-
}
|
|
24153
|
-
case "keys":
|
|
24154
|
-
return allocateProducedSandboxValue([...target.entries.keys()], options.budget);
|
|
24155
|
-
case "values":
|
|
24156
|
-
return allocateProducedSandboxValue([...target.entries.values()], options.budget);
|
|
24157
|
-
case "entries":
|
|
24158
|
-
return allocateProducedSandboxValue(
|
|
24159
|
-
[...target.entries].map(([key, value]) => [key, value]),
|
|
24160
|
-
options.budget
|
|
24161
|
-
);
|
|
24162
|
-
}
|
|
24163
|
-
}
|
|
24164
|
-
|
|
24165
|
-
// packages/safe-js/src/interp/methods/number.ts
|
|
24166
|
-
var numberMethodNames = /* @__PURE__ */ new Set([
|
|
24167
|
-
"toExponential",
|
|
24168
|
-
"toFixed",
|
|
24169
|
-
"toPrecision",
|
|
24170
|
-
"toString"
|
|
24171
|
-
]);
|
|
24172
|
-
function getNumberMember(value, property, budget) {
|
|
24173
|
-
if (!isNumberMethodName(property)) {
|
|
24174
|
-
return void 0;
|
|
24175
|
-
}
|
|
24176
|
-
return createSandboxClosure({
|
|
24177
|
-
sandbox: true,
|
|
24178
|
-
name: `Number#${property}`,
|
|
24179
|
-
call: (args) => callNumberMethod(value, property, args, budget)
|
|
24180
|
-
});
|
|
24181
|
-
}
|
|
24182
|
-
function isNumberMethodName(property) {
|
|
24183
|
-
return typeof property === "string" && numberMethodNames.has(property);
|
|
24184
|
-
}
|
|
24185
|
-
function callNumberMethod(value, methodName, args, budget) {
|
|
24186
|
-
return budget.allocateString(callNativeNumberMethod(value, methodName, args));
|
|
24187
|
-
}
|
|
24188
|
-
function callNativeNumberMethod(value, methodName, args) {
|
|
24189
|
-
switch (methodName) {
|
|
24190
|
-
case "toString":
|
|
24191
|
-
return value.toString(asValidatedRadix(args[0]));
|
|
24192
|
-
case "toExponential":
|
|
24193
|
-
return args[0] === void 0 ? value.toExponential() : value.toExponential(asValidatedFractionDigits(args[0], methodName));
|
|
24194
|
-
case "toFixed":
|
|
24195
|
-
return value.toFixed(asValidatedFractionDigits(args[0], methodName));
|
|
24196
|
-
case "toPrecision":
|
|
24197
|
-
return args[0] === void 0 ? value.toPrecision() : value.toPrecision(asValidatedPrecision(args[0]));
|
|
24198
|
-
}
|
|
24199
|
-
}
|
|
24200
|
-
function asValidatedRadix(value) {
|
|
24201
|
-
if (value === void 0) {
|
|
24202
|
-
return void 0;
|
|
24203
|
-
}
|
|
24204
|
-
const radix = toIntegerOrInfinity2(value);
|
|
24205
|
-
if (radix < 2 || radix > 36) {
|
|
24206
|
-
throw new RangeError("Number#toString radix must be between 2 and 36.");
|
|
24207
|
-
}
|
|
24208
|
-
return radix;
|
|
24209
|
-
}
|
|
24210
|
-
function asValidatedFractionDigits(value, methodName) {
|
|
24211
|
-
const digits = toIntegerOrInfinity2(value);
|
|
24212
|
-
if (digits < 0 || digits > 100) {
|
|
24213
|
-
throw new RangeError(`Number#${methodName} digits must be between 0 and 100.`);
|
|
24214
|
-
}
|
|
24215
|
-
return digits;
|
|
24216
|
-
}
|
|
24217
|
-
function asValidatedPrecision(value) {
|
|
24218
|
-
const precision = toIntegerOrInfinity2(value);
|
|
24219
|
-
if (precision < 1 || precision > 100) {
|
|
24220
|
-
throw new RangeError("Number#toPrecision precision must be between 1 and 100.");
|
|
24221
|
-
}
|
|
24222
|
-
return precision;
|
|
24223
|
-
}
|
|
24224
|
-
function toIntegerOrInfinity2(value) {
|
|
24225
|
-
const number = Number(value);
|
|
24226
|
-
if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
|
|
24227
|
-
return 0;
|
|
24228
|
-
}
|
|
24229
|
-
if (!Number.isFinite(number)) {
|
|
24230
|
-
return number;
|
|
24231
|
-
}
|
|
24232
|
-
return Math.trunc(number);
|
|
24233
|
-
}
|
|
24234
|
-
|
|
24235
|
-
// packages/safe-js/src/interp/methods/generator.ts
|
|
24236
|
-
var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
|
|
24237
|
-
function getGeneratorMember(target, property, budget) {
|
|
24238
|
-
if (typeof property !== "string" || !generatorMethodNames.has(property)) {
|
|
24239
|
-
return void 0;
|
|
24240
|
-
}
|
|
24241
|
-
return createSandboxClosure({
|
|
24242
|
-
sandbox: true,
|
|
24243
|
-
name: property,
|
|
24244
|
-
call: async ([value]) => {
|
|
24245
|
-
const iterator = getSandboxIterator(target);
|
|
24246
|
-
const result = await iterator[property](value);
|
|
24247
|
-
return allocateProducedSandboxValue(
|
|
24248
|
-
{ value: result.value, done: result.done === true },
|
|
24249
|
-
budget
|
|
24250
|
-
);
|
|
24251
|
-
}
|
|
24252
|
-
});
|
|
24253
|
-
}
|
|
24254
|
-
|
|
24255
|
-
// packages/safe-js/src/interp/regex/engine.ts
|
|
24256
|
-
function matchRegex(pattern, input, lastIndex = 0) {
|
|
24257
|
-
const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
|
|
24258
|
-
return matchRegexFrom(pattern, input, startIndex);
|
|
24259
|
-
}
|
|
24260
|
-
function matchRegexFrom(pattern, input, startIndex) {
|
|
24261
|
-
if (startIndex > input.length) {
|
|
24262
|
-
return null;
|
|
24263
|
-
}
|
|
24264
|
-
for (let attempt = startIndex; attempt <= input.length; attempt += 1) {
|
|
24265
|
-
const context = { input, flags: pattern.flags, steps: 0 };
|
|
24266
|
-
charge(context);
|
|
24267
|
-
const initialState = {
|
|
24268
|
-
position: attempt,
|
|
24269
|
-
captures: new Array(pattern.captureCount)
|
|
24270
|
-
};
|
|
24271
|
-
const result = matchNode(pattern.body, initialState, context).next();
|
|
24272
|
-
if (!result.done) {
|
|
24273
|
-
return toRegexMatch(input, attempt, result.value);
|
|
24274
|
-
}
|
|
24275
|
-
}
|
|
24276
|
-
return null;
|
|
24277
|
-
}
|
|
24278
|
-
function* matchNode(node, state, context) {
|
|
24279
|
-
charge(context);
|
|
24280
|
-
switch (node.type) {
|
|
24281
|
-
case "empty":
|
|
24282
|
-
yield state;
|
|
24283
|
-
return;
|
|
24284
|
-
case "literal":
|
|
24285
|
-
if (charactersEqual(context.input[state.position], node.value, context.flags.ignoreCase)) {
|
|
24286
|
-
yield { ...state, position: state.position + 1 };
|
|
24287
|
-
}
|
|
24288
|
-
return;
|
|
24289
|
-
case "dot":
|
|
24290
|
-
if (state.position < context.input.length && (context.flags.dotAll || !isLineTerminator(context.input[state.position]))) {
|
|
24291
|
-
yield { ...state, position: state.position + 1 };
|
|
24292
|
-
}
|
|
24293
|
-
return;
|
|
24294
|
-
case "anchor":
|
|
24295
|
-
if (matchesAnchor(node.kind, state.position, context)) {
|
|
24296
|
-
yield state;
|
|
24297
|
-
}
|
|
24298
|
-
return;
|
|
24299
|
-
case "wordBoundary": {
|
|
24300
|
-
const previousWord = state.position > 0 && isWordCharacter(context.input[state.position - 1]);
|
|
24301
|
-
const nextWord = state.position < context.input.length && isWordCharacter(context.input[state.position]);
|
|
24302
|
-
if (previousWord !== nextWord !== node.negated) {
|
|
24303
|
-
yield state;
|
|
24304
|
-
}
|
|
24305
|
-
return;
|
|
24306
|
-
}
|
|
24307
|
-
case "characterClass": {
|
|
24308
|
-
const character = context.input[state.position];
|
|
24309
|
-
if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context.flags.ignoreCase)) {
|
|
24310
|
-
yield { ...state, position: state.position + 1 };
|
|
24311
|
-
}
|
|
24312
|
-
return;
|
|
24313
|
-
}
|
|
24314
|
-
case "sequence":
|
|
24315
|
-
yield* matchSequence(node.elements, 0, state, context);
|
|
24316
|
-
return;
|
|
24317
|
-
case "alternation":
|
|
24318
|
-
for (const alternative of node.alternatives) {
|
|
24319
|
-
yield* matchNode(alternative, cloneState(state), context);
|
|
24320
|
-
}
|
|
24321
|
-
return;
|
|
24322
|
-
case "group":
|
|
24323
|
-
for (const result of matchNode(node.body, cloneState(state), context)) {
|
|
24324
|
-
if (!node.capturing || node.index === void 0) {
|
|
24325
|
-
yield result;
|
|
24326
|
-
continue;
|
|
24327
|
-
}
|
|
24328
|
-
const captures = result.captures.slice();
|
|
24329
|
-
captures[node.index - 1] = { start: state.position, end: result.position };
|
|
24330
|
-
yield { position: result.position, captures };
|
|
24331
|
-
}
|
|
24332
|
-
return;
|
|
24333
|
-
case "quantifier":
|
|
24334
|
-
yield* matchQuantifier(node, state, context, 0);
|
|
24335
|
-
}
|
|
24336
|
-
}
|
|
24337
|
-
function* matchSequence(elements, index, state, context) {
|
|
24338
|
-
charge(context);
|
|
24339
|
-
if (index === elements.length) {
|
|
24340
|
-
yield state;
|
|
24341
|
-
return;
|
|
24342
|
-
}
|
|
24343
|
-
for (const result of matchNode(elements[index], state, context)) {
|
|
24344
|
-
yield* matchSequence(elements, index + 1, result, context);
|
|
24345
|
-
}
|
|
24346
|
-
}
|
|
24347
|
-
function* matchQuantifier(node, state, context, count) {
|
|
24348
|
-
charge(context);
|
|
24349
|
-
const canRepeat = node.max === void 0 || count < node.max;
|
|
24350
|
-
if (!node.greedy && count >= node.min) {
|
|
24351
|
-
yield state;
|
|
24352
|
-
}
|
|
24353
|
-
if (canRepeat) {
|
|
24354
|
-
for (const result of matchNode(node.body, clearCaptures(node.body, state), context)) {
|
|
24355
|
-
if (result.position === state.position) {
|
|
24356
|
-
if (count >= node.min) {
|
|
24357
|
-
continue;
|
|
24358
|
-
}
|
|
24359
|
-
if (count + 1 >= node.min) {
|
|
24360
|
-
yield result;
|
|
24361
|
-
} else {
|
|
24362
|
-
yield* matchQuantifier(node, result, context, count + 1);
|
|
24363
|
-
}
|
|
24364
|
-
continue;
|
|
24503
|
+
} finally {
|
|
24504
|
+
cursor.leave();
|
|
24365
24505
|
}
|
|
24366
|
-
|
|
24506
|
+
return void 0;
|
|
24367
24507
|
}
|
|
24508
|
+
case "keys":
|
|
24509
|
+
return allocateProducedSandboxValue([...target.entries.keys()], options.budget);
|
|
24510
|
+
case "values":
|
|
24511
|
+
return allocateProducedSandboxValue([...target.entries.values()], options.budget);
|
|
24512
|
+
case "entries":
|
|
24513
|
+
return allocateProducedSandboxValue(
|
|
24514
|
+
[...target.entries].map(([key, value]) => [key, value]),
|
|
24515
|
+
options.budget
|
|
24516
|
+
);
|
|
24368
24517
|
}
|
|
24369
|
-
if (node.greedy && count >= node.min) {
|
|
24370
|
-
yield state;
|
|
24371
|
-
}
|
|
24372
|
-
}
|
|
24373
|
-
function matchesAnchor(kind, position, context) {
|
|
24374
|
-
if (kind === "start") {
|
|
24375
|
-
return position === 0 || context.flags.multiline && position > 0 && isLineTerminator(context.input[position - 1]);
|
|
24376
|
-
}
|
|
24377
|
-
return position === context.input.length || context.flags.multiline && position < context.input.length && isLineTerminator(context.input[position]);
|
|
24378
|
-
}
|
|
24379
|
-
function matchesCharacterClass(character, items, negated, ignoreCase) {
|
|
24380
|
-
const matched = items.some((item) => matchesCharacterClassItem(character, item, ignoreCase));
|
|
24381
|
-
return negated ? !matched : matched;
|
|
24382
24518
|
}
|
|
24383
|
-
|
|
24384
|
-
|
|
24385
|
-
|
|
24386
|
-
|
|
24387
|
-
|
|
24388
|
-
|
|
24389
|
-
|
|
24390
|
-
|
|
24391
|
-
|
|
24392
|
-
|
|
24393
|
-
|
|
24394
|
-
if (!ignoreCase) {
|
|
24395
|
-
return false;
|
|
24396
|
-
}
|
|
24397
|
-
const foldedCandidate = foldCharacter(character, true).charCodeAt(0);
|
|
24398
|
-
const foldedFrom = foldCharacter(item.from, true).charCodeAt(0);
|
|
24399
|
-
const foldedTo = foldCharacter(item.to, true).charCodeAt(0);
|
|
24400
|
-
return foldedCandidate >= foldedFrom && foldedCandidate <= foldedTo;
|
|
24519
|
+
|
|
24520
|
+
// packages/safe-js/src/interp/methods/number.ts
|
|
24521
|
+
var numberMethodNames = /* @__PURE__ */ new Set([
|
|
24522
|
+
"toExponential",
|
|
24523
|
+
"toFixed",
|
|
24524
|
+
"toPrecision",
|
|
24525
|
+
"toString"
|
|
24526
|
+
]);
|
|
24527
|
+
function getNumberMember(value, property, budget) {
|
|
24528
|
+
if (!isNumberMethodName(property)) {
|
|
24529
|
+
return void 0;
|
|
24401
24530
|
}
|
|
24402
|
-
|
|
24403
|
-
|
|
24404
|
-
}
|
|
24405
|
-
|
|
24406
|
-
|
|
24407
|
-
index: start,
|
|
24408
|
-
text: input.slice(start, state.position),
|
|
24409
|
-
captures: state.captures.map(
|
|
24410
|
-
(capture) => capture === void 0 ? void 0 : input.slice(capture.start, capture.end)
|
|
24411
|
-
)
|
|
24412
|
-
};
|
|
24531
|
+
return createSandboxClosure({
|
|
24532
|
+
sandbox: true,
|
|
24533
|
+
name: `Number#${property}`,
|
|
24534
|
+
call: (args) => callNumberMethod(value, property, args, budget)
|
|
24535
|
+
});
|
|
24413
24536
|
}
|
|
24414
|
-
function
|
|
24415
|
-
return
|
|
24537
|
+
function isNumberMethodName(property) {
|
|
24538
|
+
return typeof property === "string" && numberMethodNames.has(property);
|
|
24416
24539
|
}
|
|
24417
|
-
function
|
|
24418
|
-
|
|
24419
|
-
clearNodeCaptures(node, captures);
|
|
24420
|
-
return { position: state.position, captures };
|
|
24540
|
+
function callNumberMethod(value, methodName, args, budget) {
|
|
24541
|
+
return budget.allocateString(callNativeNumberMethod(value, methodName, args));
|
|
24421
24542
|
}
|
|
24422
|
-
function
|
|
24423
|
-
|
|
24424
|
-
|
|
24425
|
-
|
|
24426
|
-
|
|
24427
|
-
|
|
24428
|
-
|
|
24429
|
-
|
|
24430
|
-
|
|
24431
|
-
|
|
24432
|
-
clearNodeCaptures(element, captures);
|
|
24433
|
-
}
|
|
24434
|
-
return;
|
|
24543
|
+
function callNativeNumberMethod(value, methodName, args) {
|
|
24544
|
+
switch (methodName) {
|
|
24545
|
+
case "toString":
|
|
24546
|
+
return value.toString(asValidatedRadix(args[0]));
|
|
24547
|
+
case "toExponential":
|
|
24548
|
+
return args[0] === void 0 ? value.toExponential() : value.toExponential(asValidatedFractionDigits(args[0], methodName));
|
|
24549
|
+
case "toFixed":
|
|
24550
|
+
return value.toFixed(asValidatedFractionDigits(args[0], methodName));
|
|
24551
|
+
case "toPrecision":
|
|
24552
|
+
return args[0] === void 0 ? value.toPrecision() : value.toPrecision(asValidatedPrecision(args[0]));
|
|
24435
24553
|
}
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
|
|
24439
|
-
|
|
24440
|
-
return;
|
|
24554
|
+
}
|
|
24555
|
+
function asValidatedRadix(value) {
|
|
24556
|
+
if (value === void 0) {
|
|
24557
|
+
return void 0;
|
|
24441
24558
|
}
|
|
24442
|
-
|
|
24443
|
-
|
|
24559
|
+
const radix = toIntegerOrInfinity2(value);
|
|
24560
|
+
if (radix < 2 || radix > 36) {
|
|
24561
|
+
throw new RangeError("Number#toString radix must be between 2 and 36.");
|
|
24444
24562
|
}
|
|
24563
|
+
return radix;
|
|
24445
24564
|
}
|
|
24446
|
-
function
|
|
24447
|
-
|
|
24448
|
-
|
|
24449
|
-
}
|
|
24450
|
-
function normalizeLastIndex(lastIndex) {
|
|
24451
|
-
if (!Number.isFinite(lastIndex) || lastIndex <= 0) {
|
|
24452
|
-
return 0;
|
|
24565
|
+
function asValidatedFractionDigits(value, methodName) {
|
|
24566
|
+
const digits = toIntegerOrInfinity2(value);
|
|
24567
|
+
if (digits < 0 || digits > 100) {
|
|
24568
|
+
throw new RangeError(`Number#${methodName} digits must be between 0 and 100.`);
|
|
24453
24569
|
}
|
|
24454
|
-
return
|
|
24455
|
-
}
|
|
24456
|
-
function charactersEqual(left, right, ignoreCase) {
|
|
24457
|
-
return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
|
|
24570
|
+
return digits;
|
|
24458
24571
|
}
|
|
24459
|
-
function
|
|
24460
|
-
|
|
24461
|
-
|
|
24572
|
+
function asValidatedPrecision(value) {
|
|
24573
|
+
const precision = toIntegerOrInfinity2(value);
|
|
24574
|
+
if (precision < 1 || precision > 100) {
|
|
24575
|
+
throw new RangeError("Number#toPrecision precision must be between 1 and 100.");
|
|
24462
24576
|
}
|
|
24463
|
-
|
|
24464
|
-
|
|
24465
|
-
|
|
24577
|
+
return precision;
|
|
24578
|
+
}
|
|
24579
|
+
function toIntegerOrInfinity2(value) {
|
|
24580
|
+
const number = Number(value);
|
|
24581
|
+
if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
|
|
24582
|
+
return 0;
|
|
24466
24583
|
}
|
|
24467
|
-
if (
|
|
24468
|
-
return
|
|
24584
|
+
if (!Number.isFinite(number)) {
|
|
24585
|
+
return number;
|
|
24469
24586
|
}
|
|
24470
|
-
return
|
|
24471
|
-
}
|
|
24472
|
-
function isDigit(character) {
|
|
24473
|
-
return character >= "0" && character <= "9";
|
|
24474
|
-
}
|
|
24475
|
-
function isWordCharacter(character) {
|
|
24476
|
-
return isDigit(character) || character >= "A" && character <= "Z" || character >= "a" && character <= "z" || character === "_";
|
|
24477
|
-
}
|
|
24478
|
-
function isSpaceCharacter(character) {
|
|
24479
|
-
return character === " " || character === "\f" || character === "\n" || character === "\r" || character === " " || character === "\v" || character === "\xA0" || character === "\u1680" || character >= "\u2000" && character <= "\u200A" || character === "\u2028" || character === "\u2029" || character === "\u202F" || character === "\u205F" || character === "\u3000" || character === "\uFEFF";
|
|
24480
|
-
}
|
|
24481
|
-
function isLineTerminator(character) {
|
|
24482
|
-
return character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029";
|
|
24587
|
+
return Math.trunc(number);
|
|
24483
24588
|
}
|
|
24484
24589
|
|
|
24485
|
-
// packages/safe-js/src/interp/methods/
|
|
24486
|
-
var
|
|
24487
|
-
function
|
|
24488
|
-
|
|
24489
|
-
}
|
|
24490
|
-
function getRegexMember(target, property) {
|
|
24491
|
-
if (property === "source" || property === "flags" || property === "lastIndex") {
|
|
24492
|
-
return target[property];
|
|
24493
|
-
}
|
|
24494
|
-
if (!isRegexMethodName(property)) {
|
|
24590
|
+
// packages/safe-js/src/interp/methods/generator.ts
|
|
24591
|
+
var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
|
|
24592
|
+
function getGeneratorMember(target, property, budget) {
|
|
24593
|
+
if (typeof property !== "string" || !generatorMethodNames.has(property)) {
|
|
24495
24594
|
return void 0;
|
|
24496
24595
|
}
|
|
24497
24596
|
return createSandboxClosure({
|
|
24498
24597
|
sandbox: true,
|
|
24499
|
-
name:
|
|
24500
|
-
call: (
|
|
24598
|
+
name: property,
|
|
24599
|
+
call: async ([value]) => {
|
|
24600
|
+
const iterator = getSandboxIterator(target);
|
|
24601
|
+
const result = await iterator[property](value);
|
|
24602
|
+
return allocateProducedSandboxValue(
|
|
24603
|
+
{ value: result.value, done: result.done === true },
|
|
24604
|
+
budget
|
|
24605
|
+
);
|
|
24606
|
+
}
|
|
24501
24607
|
});
|
|
24502
24608
|
}
|
|
24503
|
-
function setRegexMember(target, property, value) {
|
|
24504
|
-
if (property !== "lastIndex") {
|
|
24505
|
-
throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
24506
|
-
}
|
|
24507
|
-
target.lastIndex = Number(value);
|
|
24508
|
-
}
|
|
24509
|
-
function callRegexMethod(target, methodName, args) {
|
|
24510
|
-
const match = executeRegex(target, String(args[0]));
|
|
24511
|
-
return methodName === "test" ? match !== null : toMatchArray(match, String(args[0]));
|
|
24512
|
-
}
|
|
24513
|
-
function executeRegex(target, input) {
|
|
24514
|
-
const pattern = getSandboxRegexPattern(target);
|
|
24515
|
-
const match = matchRegex(pattern, input, target.lastIndex);
|
|
24516
|
-
if (pattern.flags.global) {
|
|
24517
|
-
target.lastIndex = match === null ? 0 : match.index + match.text.length;
|
|
24518
|
-
}
|
|
24519
|
-
return match;
|
|
24520
|
-
}
|
|
24521
|
-
function toMatchArray(match, input) {
|
|
24522
|
-
if (match === null) {
|
|
24523
|
-
return null;
|
|
24524
|
-
}
|
|
24525
|
-
const result = [match.text, ...match.captures];
|
|
24526
|
-
Object.assign(result, { index: match.index, input, groups: void 0 });
|
|
24527
|
-
return result;
|
|
24528
|
-
}
|
|
24529
24609
|
|
|
24530
24610
|
// packages/safe-js/src/interp/methods/string.ts
|
|
24531
24611
|
var SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
|
|
@@ -26217,7 +26297,7 @@ async function evaluateBinaryExpression(node, context) {
|
|
|
26217
26297
|
if (typeof right.value !== "object" || right.value === null) {
|
|
26218
26298
|
throw new TypeError("Right-hand side of 'in' must be an object.");
|
|
26219
26299
|
}
|
|
26220
|
-
leftValue = await toPropertyKey(leftValue, context);
|
|
26300
|
+
leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
|
|
26221
26301
|
}
|
|
26222
26302
|
const value = applyBinaryOperator(node, leftValue, right.value, context);
|
|
26223
26303
|
return {
|
|
@@ -26307,7 +26387,15 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
26307
26387
|
if (member.kind === "nullish") {
|
|
26308
26388
|
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26309
26389
|
}
|
|
26310
|
-
|
|
26390
|
+
let property;
|
|
26391
|
+
let current = void 0;
|
|
26392
|
+
if (node.operator !== "=") {
|
|
26393
|
+
if (member.object === null || member.object === void 0) {
|
|
26394
|
+
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26395
|
+
}
|
|
26396
|
+
property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
26397
|
+
current = getPropertyValue(member.object, property, context);
|
|
26398
|
+
}
|
|
26311
26399
|
if (node.operator === "&&=" && !isTruthy(current)) {
|
|
26312
26400
|
return {
|
|
26313
26401
|
kind: "normal",
|
|
@@ -26334,7 +26422,11 @@ async function evaluateMemberAssignmentExpression(node, context) {
|
|
|
26334
26422
|
return right;
|
|
26335
26423
|
}
|
|
26336
26424
|
const value = node.operator === "=" || node.operator === "&&=" || node.operator === "||=" || node.operator === "??=" ? right.value : await applyCompoundAssignmentOperator(node.operator, current, right.value, context);
|
|
26337
|
-
|
|
26425
|
+
if (member.object === null || member.object === void 0) {
|
|
26426
|
+
throw new TypeError("Cannot assign properties of null or undefined.");
|
|
26427
|
+
}
|
|
26428
|
+
property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
26429
|
+
setSandboxProperty(member.object, property, value, context.budget);
|
|
26338
26430
|
return {
|
|
26339
26431
|
kind: "normal",
|
|
26340
26432
|
hasValue: true,
|
|
@@ -27273,7 +27365,10 @@ async function evaluateThrowStatement2(node, context) {
|
|
|
27273
27365
|
return evaluateThrowStatement(node, context, evaluateNode);
|
|
27274
27366
|
}
|
|
27275
27367
|
async function evaluateTryStatement2(node, context) {
|
|
27276
|
-
return evaluateTryStatement(node,
|
|
27368
|
+
return evaluateTryStatement(node, {
|
|
27369
|
+
...context,
|
|
27370
|
+
toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(context))
|
|
27371
|
+
}, evaluateNode);
|
|
27277
27372
|
}
|
|
27278
27373
|
async function evaluateUnaryExpression(node, context) {
|
|
27279
27374
|
if (node.operator === "delete") {
|
|
@@ -27318,8 +27413,8 @@ async function evaluateDeleteExpression(node, context) {
|
|
|
27318
27413
|
if (member.kind === "completion") {
|
|
27319
27414
|
return member.result;
|
|
27320
27415
|
}
|
|
27321
|
-
if (member.kind === "nullish") {
|
|
27322
|
-
if (node.argument.optional) {
|
|
27416
|
+
if (member.kind === "nullish" || member.object === null || member.object === void 0) {
|
|
27417
|
+
if (member.kind === "nullish" && node.argument.optional) {
|
|
27323
27418
|
return {
|
|
27324
27419
|
kind: "normal",
|
|
27325
27420
|
hasValue: true,
|
|
@@ -27331,7 +27426,8 @@ async function evaluateDeleteExpression(node, context) {
|
|
|
27331
27426
|
if (!isIndexableSandboxValue(member.object)) {
|
|
27332
27427
|
throw new TypeError("Unary operator 'delete' requires a sandbox object property.");
|
|
27333
27428
|
}
|
|
27334
|
-
const
|
|
27429
|
+
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
27430
|
+
const deleted = deleteSandboxProperty(member.object, property);
|
|
27335
27431
|
return {
|
|
27336
27432
|
kind: "normal",
|
|
27337
27433
|
hasValue: true,
|
|
@@ -27379,14 +27475,15 @@ async function evaluateMemberUpdateExpression(node, context) {
|
|
|
27379
27475
|
if (member.kind === "completion") {
|
|
27380
27476
|
return member.result;
|
|
27381
27477
|
}
|
|
27382
|
-
if (member.kind === "nullish") {
|
|
27478
|
+
if (member.kind === "nullish" || member.object === null || member.object === void 0) {
|
|
27383
27479
|
throw new TypeError("Cannot update properties of null or undefined.");
|
|
27384
27480
|
}
|
|
27481
|
+
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
27385
27482
|
const current = toNumber(
|
|
27386
|
-
await toNumericPrimitive(getPropertyValue(member.object,
|
|
27483
|
+
await toNumericPrimitive(getPropertyValue(member.object, property, context), context)
|
|
27387
27484
|
);
|
|
27388
27485
|
const next = node.operator === "++" ? current + 1 : current - 1;
|
|
27389
|
-
setSandboxProperty(member.object,
|
|
27486
|
+
setSandboxProperty(member.object, property, next, context.budget);
|
|
27390
27487
|
return {
|
|
27391
27488
|
kind: "normal",
|
|
27392
27489
|
hasValue: true,
|
|
@@ -27397,14 +27494,14 @@ async function evaluateMemberExpression(node, context) {
|
|
|
27397
27494
|
const member = await evaluateMemberAccess(node, context);
|
|
27398
27495
|
if (member.kind === "error") return member;
|
|
27399
27496
|
if (member.kind === "completion") return member.result;
|
|
27400
|
-
if (member.kind === "nullish") {
|
|
27401
|
-
if (node.optional) return { kind: "normal", hasValue: true, value: void 0 };
|
|
27497
|
+
if (member.kind === "nullish" || member.object === null || member.object === void 0) {
|
|
27498
|
+
if (member.kind === "nullish" && node.optional) return { kind: "normal", hasValue: true, value: void 0 };
|
|
27402
27499
|
throw new TypeError("Cannot read properties of null or undefined.");
|
|
27403
27500
|
}
|
|
27404
27501
|
return {
|
|
27405
27502
|
kind: "normal",
|
|
27406
27503
|
hasValue: true,
|
|
27407
|
-
value: getPropertyValue(member.object, member.property, context)
|
|
27504
|
+
value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
|
|
27408
27505
|
};
|
|
27409
27506
|
}
|
|
27410
27507
|
function getPropertyValue(target, property, context) {
|
|
@@ -27419,7 +27516,7 @@ function getPropertyValue(target, property, context) {
|
|
|
27419
27516
|
if (isSandboxGenerator(target)) return getGeneratorMember(target, property, context.budget);
|
|
27420
27517
|
if (isSandboxClosure(target)) return getClosureMemberValue(target, property, context);
|
|
27421
27518
|
if (isSandboxPromise(target)) return getPromiseMember(property, context.budget);
|
|
27422
|
-
if (isSandboxRegex(target)) return getRegexMember(target, property);
|
|
27519
|
+
if (isSandboxRegex(target)) return getRegexMember(target, property, context.budget);
|
|
27423
27520
|
if (!isIndexableSandboxValue(target)) {
|
|
27424
27521
|
throw new TypeError("Attempted to read a property from a non-object value.");
|
|
27425
27522
|
}
|
|
@@ -27429,6 +27526,7 @@ function createPatternContext(context, scope = context.scope, evaluate = evaluat
|
|
|
27429
27526
|
const evaluationContext = { ...context, scope };
|
|
27430
27527
|
return {
|
|
27431
27528
|
evaluate: (node) => evaluate(node, evaluationContext),
|
|
27529
|
+
toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
|
|
27432
27530
|
getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
|
|
27433
27531
|
setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget)
|
|
27434
27532
|
};
|
|
@@ -27523,21 +27621,8 @@ async function evaluateMemberAccess(node, context) {
|
|
|
27523
27621
|
kind: "nullish"
|
|
27524
27622
|
};
|
|
27525
27623
|
}
|
|
27526
|
-
const property = node.computed ? await
|
|
27527
|
-
if (
|
|
27528
|
-
return property.result.kind === "error" ? {
|
|
27529
|
-
kind: "error",
|
|
27530
|
-
error: property.result.error
|
|
27531
|
-
} : {
|
|
27532
|
-
kind: "completion",
|
|
27533
|
-
result: property.result
|
|
27534
|
-
};
|
|
27535
|
-
}
|
|
27536
|
-
if (object.value === null || object.value === void 0) {
|
|
27537
|
-
return {
|
|
27538
|
-
kind: "nullish"
|
|
27539
|
-
};
|
|
27540
|
-
}
|
|
27624
|
+
const property = node.computed ? await evaluateNode(node.property, context) : { kind: "normal", value: getStaticPropertyName2(node.property) };
|
|
27625
|
+
if (property.kind !== "normal") return { kind: "completion", result: property };
|
|
27541
27626
|
return {
|
|
27542
27627
|
kind: "resolved",
|
|
27543
27628
|
object: object.value,
|
|
@@ -27552,13 +27637,10 @@ async function evaluateMemberProperty(node, context) {
|
|
|
27552
27637
|
result: property
|
|
27553
27638
|
};
|
|
27554
27639
|
}
|
|
27555
|
-
|
|
27556
|
-
|
|
27557
|
-
|
|
27558
|
-
|
|
27559
|
-
};
|
|
27560
|
-
}
|
|
27561
|
-
throw new TypeError("Computed property access requires a string or number key.");
|
|
27640
|
+
return {
|
|
27641
|
+
ok: true,
|
|
27642
|
+
value: await toPropertyKey(property.value, context.budget, createCoercionContext(context))
|
|
27643
|
+
};
|
|
27562
27644
|
}
|
|
27563
27645
|
async function evaluateObjectPropertyKey(node, context) {
|
|
27564
27646
|
if (!node.computed) {
|
|
@@ -27582,15 +27664,15 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
27582
27664
|
if (node.callee.type !== "MemberExpression") {
|
|
27583
27665
|
throw new TypeError("Expected member call expression.");
|
|
27584
27666
|
}
|
|
27585
|
-
const
|
|
27586
|
-
if (
|
|
27587
|
-
return
|
|
27667
|
+
const reference = await evaluateMemberAccess(node.callee, context);
|
|
27668
|
+
if (reference.kind === "error") {
|
|
27669
|
+
return reference;
|
|
27588
27670
|
}
|
|
27589
|
-
if (
|
|
27590
|
-
return
|
|
27671
|
+
if (reference.kind === "completion") {
|
|
27672
|
+
return reference.result;
|
|
27591
27673
|
}
|
|
27592
|
-
if (
|
|
27593
|
-
if (
|
|
27674
|
+
if (reference.kind === "nullish" || reference.object === null || reference.object === void 0) {
|
|
27675
|
+
if (reference.kind === "nullish") {
|
|
27594
27676
|
return {
|
|
27595
27677
|
kind: "normal",
|
|
27596
27678
|
hasValue: true,
|
|
@@ -27599,6 +27681,10 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
27599
27681
|
}
|
|
27600
27682
|
throw new TypeError("Cannot read properties of null or undefined.");
|
|
27601
27683
|
}
|
|
27684
|
+
const member = {
|
|
27685
|
+
...reference,
|
|
27686
|
+
property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
|
|
27687
|
+
};
|
|
27602
27688
|
if (typeof member.object === "string" && isStringMethodName(member.property)) {
|
|
27603
27689
|
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
27604
27690
|
}
|
|
@@ -27695,7 +27781,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
27695
27781
|
if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
|
|
27696
27782
|
return evaluateResolvedCallExpression(
|
|
27697
27783
|
node,
|
|
27698
|
-
getRegexMember(member.object, member.property),
|
|
27784
|
+
getRegexMember(member.object, member.property, context.budget),
|
|
27699
27785
|
context,
|
|
27700
27786
|
member.object
|
|
27701
27787
|
);
|
|
@@ -27930,23 +28016,13 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
27930
28016
|
return hasSandboxProperty(right, left, context);
|
|
27931
28017
|
}
|
|
27932
28018
|
}
|
|
27933
|
-
|
|
27934
|
-
|
|
27935
|
-
for (const name of ["toString", "valueOf"]) {
|
|
27936
|
-
const method = getMemberValue(value, name, context);
|
|
27937
|
-
if (!isSandboxClosure(method)) continue;
|
|
27938
|
-
const primitive = await invokeSandboxClosure(method, [], context, context.callStack, void 0, value);
|
|
27939
|
-
if (primitive === null || typeof primitive !== "object") {
|
|
27940
|
-
return context.budget.allocateString(String(primitive));
|
|
27941
|
-
}
|
|
27942
|
-
}
|
|
27943
|
-
throw new TypeError("Cannot convert object to primitive value.");
|
|
27944
|
-
}
|
|
27945
|
-
return sandboxString(value, context.budget, {
|
|
28019
|
+
function createCoercionContext(context) {
|
|
28020
|
+
return {
|
|
27946
28021
|
stack: context.callStack,
|
|
27947
28022
|
thisValue: void 0,
|
|
28023
|
+
compilation: context.compilation,
|
|
27948
28024
|
invokeClosure: (closure, args, thisValue) => invokeSandboxClosure(closure, args, context, context.callStack, void 0, thisValue)
|
|
27949
|
-
}
|
|
28025
|
+
};
|
|
27950
28026
|
}
|
|
27951
28027
|
function hasSandboxProperty(value, key, context) {
|
|
27952
28028
|
let current = value;
|
|
@@ -32818,4 +32894,4 @@ export {
|
|
|
32818
32894
|
FileSnapshotBackend,
|
|
32819
32895
|
run
|
|
32820
32896
|
};
|
|
32821
|
-
//# sourceMappingURL=chunk-
|
|
32897
|
+
//# sourceMappingURL=chunk-774EXZKX.js.map
|