poe-code 14.0.74 → 14.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1283 -144
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-js/dist/chunks/{chunk-YEZOXLY4.js → chunk-UZYQWFMY.js} +1233 -143
- package/packages/safe-js/dist/chunks/chunk-UZYQWFMY.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-2J6W3YGB.js → chunk-VD2AS4E4.js} +2 -2
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/index.js.map +1 -1
- package/packages/safe-js/dist/interp/bigint-operators.d.ts +3 -0
- package/packages/safe-js/dist/interp/bigint-operators.js +62 -0
- package/packages/safe-js/dist/interp/boxed.d.ts +2 -2
- package/packages/safe-js/dist/interp/boxed.js +4 -1
- package/packages/safe-js/dist/interp/globals/bigint.d.ts +2 -0
- package/packages/safe-js/dist/interp/globals/bigint.js +85 -0
- package/packages/safe-js/dist/interp/globals/console-json.js +57 -24
- package/packages/safe-js/dist/interp/globals/object-array.js +1 -1
- package/packages/safe-js/dist/interp/globals/regex.js +108 -2
- package/packages/safe-js/dist/interp/globals.d.ts +1 -0
- package/packages/safe-js/dist/interp/globals.js +2 -0
- package/packages/safe-js/dist/interp/host-bridge.js +2 -0
- package/packages/safe-js/dist/interp/interpreter.js +59 -12
- package/packages/safe-js/dist/interp/iteration.js +5 -2
- package/packages/safe-js/dist/interp/methods/number.js +1 -1
- package/packages/safe-js/dist/interp/methods/regex-split.d.ts +3 -0
- package/packages/safe-js/dist/interp/methods/regex-split.js +102 -0
- package/packages/safe-js/dist/interp/methods/regex.d.ts +1 -1
- package/packages/safe-js/dist/interp/methods/regex.js +16 -5
- package/packages/safe-js/dist/interp/methods/regexp-iterator.d.ts +5 -1
- package/packages/safe-js/dist/interp/methods/regexp-iterator.js +59 -7
- package/packages/safe-js/dist/interp/methods/string.js +9 -9
- package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
- package/packages/safe-js/dist/interp/object-model.js +4 -1
- package/packages/safe-js/dist/interp/regex/compile-guard.js +26 -4
- package/packages/safe-js/dist/interp/regex/engine.d.ts +4 -0
- package/packages/safe-js/dist/interp/regex/engine.js +230 -30
- package/packages/safe-js/dist/interp/regex/parse.d.ts +42 -4
- package/packages/safe-js/dist/interp/regex/parse.js +429 -25
- package/packages/safe-js/dist/interp/regexp-iterator.d.ts +4 -2
- package/packages/safe-js/dist/interp/regexp-iterator.js +6 -1
- package/packages/safe-js/dist/interp/string-coercion.d.ts +1 -1
- package/packages/safe-js/dist/interp/string-coercion.js +8 -3
- package/packages/safe-js/dist/interp/values.d.ts +1 -1
- package/packages/safe-js/dist/interp/values.js +10 -3
- package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +2 -0
- package/packages/safe-js/dist/lint/rules/AS-missing-async.js +2 -0
- package/packages/safe-js/dist/lint/rules/known-globals.d.ts +1 -1
- package/packages/safe-js/dist/lint/rules/known-globals.js +1 -0
- package/packages/safe-js/dist/parse/parser.d.ts +6 -1
- package/packages/safe-js/dist/parse/parser.js +8 -0
- package/packages/safe-js/dist/parse/tokenizer.js +12 -4
- package/packages/safe-js/dist/parse.d.ts +1 -1
- package/packages/safe-js/dist/snapshot/bigint.d.ts +1 -0
- package/packages/safe-js/dist/snapshot/bigint.js +14 -0
- package/packages/safe-js/dist/snapshot/dump-format.js +12 -2
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +6 -0
- package/packages/safe-js/dist/snapshot/replay-data.js +23 -5
- package/packages/safe-js/dist/snapshot/restore.js +10 -2
- package/packages/safe-js/dist/snapshot/serialize.d.ts +4 -1
- package/packages/safe-js/dist/snapshot/serialize.js +6 -1
- package/packages/safe-js/dist/snapshot/validation.js +27 -0
- package/packages/safe-js/dist/chunks/chunk-YEZOXLY4.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-2J6W3YGB.js.map → chunk-VD2AS4E4.js.map} +0 -0
|
@@ -711,7 +711,7 @@ var RegexCompileGuard = class {
|
|
|
711
711
|
this.work(flags.length);
|
|
712
712
|
}
|
|
713
713
|
retain(pattern, valueUnits = 0) {
|
|
714
|
-
const units =
|
|
714
|
+
const units = measurePattern(pattern);
|
|
715
715
|
if (this.ticket !== void 0) {
|
|
716
716
|
this.ticket.owner.budget.resizeCompileTicket(this.ticket, units + valueUnits);
|
|
717
717
|
}
|
|
@@ -728,7 +728,15 @@ var RegexCompileGuard = class {
|
|
|
728
728
|
}
|
|
729
729
|
};
|
|
730
730
|
function regexCompiledData(pattern) {
|
|
731
|
-
return compiledData.get(pattern) ?? { units:
|
|
731
|
+
return compiledData.get(pattern) ?? { units: measurePattern(pattern) };
|
|
732
|
+
}
|
|
733
|
+
function measurePattern(pattern) {
|
|
734
|
+
let units = 10 + pattern.source.length + measureNode(pattern.body);
|
|
735
|
+
if (pattern.groups !== void 0) {
|
|
736
|
+
units += 1;
|
|
737
|
+
for (const [name, indices] of Object.entries(pattern.groups)) units += name.length + 2 + indices.length;
|
|
738
|
+
}
|
|
739
|
+
return units;
|
|
732
740
|
}
|
|
733
741
|
function measureNode(node) {
|
|
734
742
|
switch (node.type) {
|
|
@@ -737,13 +745,18 @@ function measureNode(node) {
|
|
|
737
745
|
return 2;
|
|
738
746
|
case "literal":
|
|
739
747
|
return 3 + node.value.length;
|
|
748
|
+
case "namedBackreference":
|
|
749
|
+
return 3 + node.name.length;
|
|
740
750
|
case "anchor":
|
|
741
751
|
case "wordBoundary":
|
|
752
|
+
case "backreference":
|
|
742
753
|
return 3;
|
|
743
754
|
case "characterClass": {
|
|
744
755
|
let usage = 5 + node.items.length;
|
|
756
|
+
if (node.operation !== void 0) usage += 1 + node.operation.length;
|
|
757
|
+
if (node.strings !== void 0) usage += 1;
|
|
745
758
|
for (const item of node.items) {
|
|
746
|
-
usage += item.type === "character" ? 3 + item.value.length : item.type === "range" ? 4 + item.from.length + item.to.length : 4;
|
|
759
|
+
usage += item.type === "character" ? 3 + item.value.length : item.type === "range" ? 4 + item.from.length + item.to.length : item.type === "property" ? 4 + item.value.length + (item.strings === void 0 ? 0 : 1) : item.type === "set" ? 3 + measureNode({ type: "characterClass", ...item.value }) : item.type === "strings" ? 4 + item.values.reduce((total, value) => total + 1 + value.length, 0) : 4;
|
|
747
760
|
}
|
|
748
761
|
return usage;
|
|
749
762
|
}
|
|
@@ -755,7 +768,10 @@ function measureNode(node) {
|
|
|
755
768
|
return usage;
|
|
756
769
|
}
|
|
757
770
|
case "group":
|
|
758
|
-
return 5 + measureNode(node.body);
|
|
771
|
+
return 5 + measureNode(node.body) + (node.name === void 0 ? 0 : 1 + node.name.length) + (node.modifiers === void 0 ? 0 : 2 + Object.keys(node.modifiers).length);
|
|
772
|
+
case "lookahead":
|
|
773
|
+
case "lookbehind":
|
|
774
|
+
return 4 + measureNode(node.body);
|
|
759
775
|
case "quantifier":
|
|
760
776
|
return (Object.hasOwn(node, "max") ? 6 : 5) + measureNode(node.body);
|
|
761
777
|
}
|
|
@@ -1239,7 +1255,7 @@ var Lexer = class {
|
|
|
1239
1255
|
this.advance();
|
|
1240
1256
|
this.advance();
|
|
1241
1257
|
this.consumeDigitsForBase(isHexDigit, "hexadecimal");
|
|
1242
|
-
this.
|
|
1258
|
+
if (this.currentChar() === "n") this.advance();
|
|
1243
1259
|
this.rejectInvalidNumericLiteralContinuation();
|
|
1244
1260
|
return this.source.slice(start.offset, this.index);
|
|
1245
1261
|
}
|
|
@@ -1247,7 +1263,7 @@ var Lexer = class {
|
|
|
1247
1263
|
this.advance();
|
|
1248
1264
|
this.advance();
|
|
1249
1265
|
this.consumeDigitsForBase(isBinaryDigit, "binary");
|
|
1250
|
-
this.
|
|
1266
|
+
if (this.currentChar() === "n") this.advance();
|
|
1251
1267
|
this.rejectInvalidNumericLiteralContinuation();
|
|
1252
1268
|
return this.source.slice(start.offset, this.index);
|
|
1253
1269
|
}
|
|
@@ -1255,7 +1271,7 @@ var Lexer = class {
|
|
|
1255
1271
|
this.advance();
|
|
1256
1272
|
this.advance();
|
|
1257
1273
|
this.consumeDigitsForBase(isOctalDigit, "octal");
|
|
1258
|
-
this.
|
|
1274
|
+
if (this.currentChar() === "n") this.advance();
|
|
1259
1275
|
this.rejectInvalidNumericLiteralContinuation();
|
|
1260
1276
|
return this.source.slice(start.offset, this.index);
|
|
1261
1277
|
}
|
|
@@ -1269,6 +1285,11 @@ var Lexer = class {
|
|
|
1269
1285
|
}
|
|
1270
1286
|
}
|
|
1271
1287
|
this.consumeDecimalDigits();
|
|
1288
|
+
if (this.currentChar() === "n") {
|
|
1289
|
+
this.advance();
|
|
1290
|
+
this.rejectInvalidNumericLiteralContinuation();
|
|
1291
|
+
return this.source.slice(start.offset, this.index);
|
|
1292
|
+
}
|
|
1272
1293
|
if (this.currentChar() === "." && (this.peekChar(1) !== "." || this.peekChar(2) !== ".")) {
|
|
1273
1294
|
this.advance();
|
|
1274
1295
|
this.consumeOptionalDecimalDigits();
|
|
@@ -1367,7 +1388,7 @@ var Lexer = class {
|
|
|
1367
1388
|
}
|
|
1368
1389
|
rejectBigIntSuffix() {
|
|
1369
1390
|
if (this.currentChar() === "n") {
|
|
1370
|
-
this.syntaxError("BigInt
|
|
1391
|
+
this.syntaxError("BigInt literals cannot contain a fraction or exponent", this.position());
|
|
1371
1392
|
}
|
|
1372
1393
|
}
|
|
1373
1394
|
rejectInvalidNumericLiteralContinuation() {
|
|
@@ -2045,6 +2066,8 @@ function createIdentifier(token, name) {
|
|
|
2045
2066
|
}
|
|
2046
2067
|
|
|
2047
2068
|
// packages/safe-js/src/interp/regex/parse.ts
|
|
2069
|
+
var groupNameStart = /^[$_\p{ID_Start}]$/u;
|
|
2070
|
+
var groupNamePart = /^[$\u200c\u200d\p{ID_Continue}]$/u;
|
|
2048
2071
|
function parseRegex(source, flags = "", compilation, valueUnits = 0) {
|
|
2049
2072
|
const guard = new RegexCompileGuard(compilation);
|
|
2050
2073
|
try {
|
|
@@ -2052,10 +2075,11 @@ function parseRegex(source, flags = "", compilation, valueUnits = 0) {
|
|
|
2052
2075
|
guard.checkLength(flags.length, true);
|
|
2053
2076
|
guard.allocate(5 + valueUnits);
|
|
2054
2077
|
const parsedFlags = parseFlags(flags, guard);
|
|
2055
|
-
const parser = new RegexParser(source, guard);
|
|
2078
|
+
const parser = new RegexParser(source, guard, parsedFlags.unicode || parsedFlags.unicodeSets, parsedFlags.unicodeSets);
|
|
2056
2079
|
const body = parser.parse();
|
|
2057
2080
|
guard.allocate(5 + source.length);
|
|
2058
2081
|
const pattern = { source, flags: parsedFlags, captureCount: parser.captureCount, body };
|
|
2082
|
+
if (Object.keys(parser.namedGroups).length > 0) pattern.groups = parser.namedGroups;
|
|
2059
2083
|
guard.retain(pattern, valueUnits);
|
|
2060
2084
|
return pattern;
|
|
2061
2085
|
} finally {
|
|
@@ -2063,14 +2087,21 @@ function parseRegex(source, flags = "", compilation, valueUnits = 0) {
|
|
|
2063
2087
|
}
|
|
2064
2088
|
}
|
|
2065
2089
|
var RegexParser = class {
|
|
2066
|
-
constructor(source, guard) {
|
|
2090
|
+
constructor(source, guard, unicode, unicodeSets) {
|
|
2067
2091
|
this.source = source;
|
|
2068
2092
|
this.guard = guard;
|
|
2093
|
+
this.unicode = unicode;
|
|
2094
|
+
this.unicodeSets = unicodeSets;
|
|
2069
2095
|
}
|
|
2070
2096
|
source;
|
|
2071
2097
|
guard;
|
|
2098
|
+
unicode;
|
|
2099
|
+
unicodeSets;
|
|
2072
2100
|
captureCount = 0;
|
|
2073
2101
|
cursor = 0;
|
|
2102
|
+
totalCaptureCount;
|
|
2103
|
+
hasNamedCaptures = false;
|
|
2104
|
+
namedGroups = /* @__PURE__ */ Object.create(null);
|
|
2074
2105
|
get position() {
|
|
2075
2106
|
return this.cursor;
|
|
2076
2107
|
}
|
|
@@ -2086,6 +2117,7 @@ var RegexParser = class {
|
|
|
2086
2117
|
}
|
|
2087
2118
|
this.fail(`Unexpected character '${this.peek()}'`);
|
|
2088
2119
|
}
|
|
2120
|
+
if (this.unicode || Object.keys(this.namedGroups).length > 0) this.validateNamedGroups(body);
|
|
2089
2121
|
return body;
|
|
2090
2122
|
}
|
|
2091
2123
|
parseAlternation() {
|
|
@@ -2119,15 +2151,20 @@ var RegexParser = class {
|
|
|
2119
2151
|
parseQuantifiedAtom() {
|
|
2120
2152
|
const quantifierStart = this.position;
|
|
2121
2153
|
const current = this.peek();
|
|
2122
|
-
if (current === "*" || current === "+" || current === "?" || current === "{") {
|
|
2154
|
+
if (current === "*" || current === "+" || current === "?" || current === "{" && this.unicode) {
|
|
2123
2155
|
this.fail("Nothing to repeat", quantifierStart);
|
|
2124
2156
|
}
|
|
2157
|
+
if (current === "{") {
|
|
2158
|
+
const quantifier2 = this.parseQuantifier();
|
|
2159
|
+
this.position = quantifierStart;
|
|
2160
|
+
if (quantifier2 !== void 0) this.fail("Nothing to repeat", quantifierStart);
|
|
2161
|
+
}
|
|
2125
2162
|
const body = this.parseAtom();
|
|
2126
2163
|
const quantifier = this.parseQuantifier();
|
|
2127
2164
|
if (quantifier === void 0) {
|
|
2128
2165
|
return body;
|
|
2129
2166
|
}
|
|
2130
|
-
if (body.type === "anchor" || body.type === "wordBoundary") {
|
|
2167
|
+
if (body.type === "anchor" || body.type === "wordBoundary" || body.type === "lookbehind" || this.unicode && body.type === "lookahead") {
|
|
2131
2168
|
this.fail("Invalid quantifier target", quantifierStart);
|
|
2132
2169
|
}
|
|
2133
2170
|
const greedy = this.peek() !== "?";
|
|
@@ -2138,7 +2175,7 @@ var RegexParser = class {
|
|
|
2138
2175
|
return { type: "quantifier", body, ...quantifier, greedy };
|
|
2139
2176
|
}
|
|
2140
2177
|
parseAtom() {
|
|
2141
|
-
const character = this.
|
|
2178
|
+
const character = this.takeCharacter();
|
|
2142
2179
|
switch (character) {
|
|
2143
2180
|
case ".":
|
|
2144
2181
|
this.guard.allocate(2);
|
|
@@ -2156,12 +2193,17 @@ var RegexParser = class {
|
|
|
2156
2193
|
case "\\":
|
|
2157
2194
|
return this.parseEscape(false, this.position - 1);
|
|
2158
2195
|
default:
|
|
2196
|
+
if (this.unicode && (character === "]" || character === "}")) this.fail("Invalid Unicode pattern character");
|
|
2159
2197
|
this.guard.allocate(3 + character.length);
|
|
2160
2198
|
return { type: "literal", value: character };
|
|
2161
2199
|
}
|
|
2162
2200
|
}
|
|
2163
2201
|
parseGroup(start) {
|
|
2164
2202
|
let capturing = true;
|
|
2203
|
+
let name;
|
|
2204
|
+
let modifiers;
|
|
2205
|
+
let assertionNegated;
|
|
2206
|
+
let lookbehind = false;
|
|
2165
2207
|
if (this.peek() === "?") {
|
|
2166
2208
|
this.guard.allocate(Math.min(3, this.source.length - this.position));
|
|
2167
2209
|
this.guard.work(Math.min(3, this.source.length - this.position));
|
|
@@ -2170,17 +2212,33 @@ var RegexParser = class {
|
|
|
2170
2212
|
capturing = false;
|
|
2171
2213
|
this.position += 2;
|
|
2172
2214
|
} else if (extension.startsWith("?=") || extension.startsWith("?!")) {
|
|
2173
|
-
|
|
2215
|
+
capturing = false;
|
|
2216
|
+
assertionNegated = extension.startsWith("?!");
|
|
2217
|
+
this.position += 2;
|
|
2174
2218
|
} else if (extension.startsWith("?<=") || extension.startsWith("?<!")) {
|
|
2175
|
-
|
|
2219
|
+
capturing = false;
|
|
2220
|
+
assertionNegated = extension.startsWith("?<!");
|
|
2221
|
+
lookbehind = true;
|
|
2222
|
+
this.position += 3;
|
|
2176
2223
|
} else if (extension.startsWith("?<")) {
|
|
2177
|
-
this.
|
|
2224
|
+
this.position += 2;
|
|
2225
|
+
name = this.parseGroupName(start);
|
|
2226
|
+
} else if ("ims-".includes(extension[1] ?? "") && extension.length > 1) {
|
|
2227
|
+
capturing = false;
|
|
2228
|
+
this.position++;
|
|
2229
|
+
modifiers = this.parseModifiers(start);
|
|
2178
2230
|
} else {
|
|
2179
2231
|
this.fail("Unsupported group construct", start);
|
|
2180
2232
|
}
|
|
2181
2233
|
}
|
|
2182
2234
|
if (capturing) this.guard.allocate(1);
|
|
2183
2235
|
const index = capturing ? ++this.captureCount : void 0;
|
|
2236
|
+
if (name !== void 0) {
|
|
2237
|
+
this.guard.allocate(name.length + 2);
|
|
2238
|
+
const indices = this.namedGroups[name] ??= [];
|
|
2239
|
+
this.guard.array(indices.length + 1);
|
|
2240
|
+
indices.push(index);
|
|
2241
|
+
}
|
|
2184
2242
|
this.guard.enterGroup();
|
|
2185
2243
|
let body;
|
|
2186
2244
|
try {
|
|
@@ -2192,10 +2250,40 @@ var RegexParser = class {
|
|
|
2192
2250
|
this.fail("Unterminated group", start);
|
|
2193
2251
|
}
|
|
2194
2252
|
this.position += 1;
|
|
2253
|
+
if (assertionNegated !== void 0) {
|
|
2254
|
+
this.guard.allocate(4);
|
|
2255
|
+
return { type: lookbehind ? "lookbehind" : "lookahead", negated: assertionNegated, body };
|
|
2256
|
+
}
|
|
2195
2257
|
this.guard.allocate(5);
|
|
2196
|
-
return {
|
|
2258
|
+
return {
|
|
2259
|
+
type: "group",
|
|
2260
|
+
capturing,
|
|
2261
|
+
index,
|
|
2262
|
+
body,
|
|
2263
|
+
...name === void 0 ? {} : { name },
|
|
2264
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
2265
|
+
};
|
|
2266
|
+
}
|
|
2267
|
+
parseModifiers(start) {
|
|
2268
|
+
this.guard.allocate(2);
|
|
2269
|
+
const modifiers = {};
|
|
2270
|
+
let enabled = true;
|
|
2271
|
+
while (!this.atEnd() && this.peek() !== ":") {
|
|
2272
|
+
const flag = this.take();
|
|
2273
|
+
if (flag === "-" && enabled) {
|
|
2274
|
+
enabled = false;
|
|
2275
|
+
continue;
|
|
2276
|
+
}
|
|
2277
|
+
const name = flag === "i" ? "ignoreCase" : flag === "m" ? "multiline" : flag === "s" ? "dotAll" : void 0;
|
|
2278
|
+
if (name === void 0 || Object.hasOwn(modifiers, name)) this.fail("Invalid regex modifiers", start);
|
|
2279
|
+
this.guard.allocate(1);
|
|
2280
|
+
modifiers[name] = enabled;
|
|
2281
|
+
}
|
|
2282
|
+
if (this.take() !== ":" || Object.keys(modifiers).length === 0) this.fail("Invalid regex modifiers", start);
|
|
2283
|
+
return modifiers;
|
|
2197
2284
|
}
|
|
2198
2285
|
parseCharacterClass(start) {
|
|
2286
|
+
if (this.unicodeSets) return { type: "characterClass", ...this.parseUnicodeSet(start) };
|
|
2199
2287
|
const negated = this.peek() === "^";
|
|
2200
2288
|
if (negated) {
|
|
2201
2289
|
this.position += 1;
|
|
@@ -2215,9 +2303,13 @@ var RegexParser = class {
|
|
|
2215
2303
|
this.position += 1;
|
|
2216
2304
|
const right = this.parseClassItem(start);
|
|
2217
2305
|
if (left.type !== "character" || right.type !== "character") {
|
|
2218
|
-
this.fail("Character class ranges require literal endpoints", rangePosition);
|
|
2306
|
+
if (this.unicode) this.fail("Character class ranges require literal endpoints", rangePosition);
|
|
2307
|
+
this.guard.array(items.length + 3);
|
|
2308
|
+
this.guard.allocate(4);
|
|
2309
|
+
items.push(left, { type: "character", value: "-" }, right);
|
|
2310
|
+
continue;
|
|
2219
2311
|
}
|
|
2220
|
-
if (left.value.
|
|
2312
|
+
if (left.value.codePointAt(0) > right.value.codePointAt(0)) {
|
|
2221
2313
|
this.fail("Character class range is out of order", rangePosition);
|
|
2222
2314
|
}
|
|
2223
2315
|
this.guard.allocate(4 + left.value.length + right.value.length);
|
|
@@ -2246,26 +2338,193 @@ var RegexParser = class {
|
|
|
2246
2338
|
this.fail("Unsupported character class escape", escapeStart);
|
|
2247
2339
|
}
|
|
2248
2340
|
this.guard.allocate(4);
|
|
2249
|
-
return { type: "character", value: this.
|
|
2341
|
+
return { type: "character", value: this.takeCharacter() };
|
|
2342
|
+
}
|
|
2343
|
+
parseUnicodeSet(start) {
|
|
2344
|
+
this.guard.enterGroup();
|
|
2345
|
+
try {
|
|
2346
|
+
const negated = this.peek() === "^";
|
|
2347
|
+
if (negated) this.position++;
|
|
2348
|
+
this.guard.allocate(5);
|
|
2349
|
+
const items = [];
|
|
2350
|
+
let operation;
|
|
2351
|
+
while (!this.atEnd() && this.peek() !== "]") {
|
|
2352
|
+
this.guard.array(items.length + 1);
|
|
2353
|
+
let item = this.parseUnicodeSetItem(start);
|
|
2354
|
+
if (this.peek() === "-" && this.source[this.position + 1] !== "-") {
|
|
2355
|
+
this.position++;
|
|
2356
|
+
const right = this.parseUnicodeSetItem(start);
|
|
2357
|
+
if (item.type !== "character" || right.type !== "character") this.fail("Invalid set range", start);
|
|
2358
|
+
if (item.value.codePointAt(0) > right.value.codePointAt(0)) this.fail("Set range is out of order", start);
|
|
2359
|
+
this.guard.allocate(4 + item.value.length + right.value.length);
|
|
2360
|
+
item = { type: "range", from: item.value, to: right.value };
|
|
2361
|
+
}
|
|
2362
|
+
if (operation !== void 0 && item.type === "range") this.fail("Set operations require nested ranges", start);
|
|
2363
|
+
items.push(item);
|
|
2364
|
+
const operator = this.source.slice(this.position, this.position + 2);
|
|
2365
|
+
if (operator === "&&" || operator === "--") {
|
|
2366
|
+
const next = operator === "&&" ? "intersection" : "subtraction";
|
|
2367
|
+
if (operation === void 0 && (items.length !== 1 || item.type === "range") || operation !== void 0 && operation !== next) this.fail("Mixed set operations", start);
|
|
2368
|
+
if (operation === void 0) this.guard.allocate(1 + next.length);
|
|
2369
|
+
operation = next;
|
|
2370
|
+
this.position += 2;
|
|
2371
|
+
if (this.peek() === "]" || this.atEnd()) this.fail("Missing set operand", start);
|
|
2372
|
+
} else if (operation !== void 0 && this.peek() !== "]") this.fail("Missing set operator", start);
|
|
2373
|
+
}
|
|
2374
|
+
if (this.take() !== "]") this.fail("Unterminated character set", start);
|
|
2375
|
+
const mayContainStrings = (item) => {
|
|
2376
|
+
if (item.type === "set") return item.value.strings === true;
|
|
2377
|
+
if (item.type === "property") return item.strings === true;
|
|
2378
|
+
if (item.type === "strings") return item.values.some((value) => value.length !== ((value.codePointAt(0) ?? 0) > 65535 ? 2 : 1));
|
|
2379
|
+
return false;
|
|
2380
|
+
};
|
|
2381
|
+
const strings = operation === "intersection" ? items.every(mayContainStrings) : operation === "subtraction" ? mayContainStrings(items[0]) : items.some(mayContainStrings);
|
|
2382
|
+
if (negated && strings) this.fail("Cannot complement a set containing strings", start);
|
|
2383
|
+
if (strings) this.guard.allocate(1);
|
|
2384
|
+
return { negated, items, ...operation === void 0 ? {} : { operation }, ...strings ? { strings: true } : {} };
|
|
2385
|
+
} finally {
|
|
2386
|
+
this.guard.leaveGroup();
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
parseUnicodeSetItem(start) {
|
|
2390
|
+
if (this.peek() === "[") {
|
|
2391
|
+
this.position++;
|
|
2392
|
+
this.guard.allocate(3);
|
|
2393
|
+
return { type: "set", value: this.parseUnicodeSet(start) };
|
|
2394
|
+
}
|
|
2395
|
+
if (this.source.startsWith("\\q{", this.position)) {
|
|
2396
|
+
this.position += 3;
|
|
2397
|
+
this.guard.allocate(4);
|
|
2398
|
+
const values = [];
|
|
2399
|
+
let value2 = "";
|
|
2400
|
+
while (!this.atEnd()) {
|
|
2401
|
+
if (this.peek() === "|" || this.peek() === "}") {
|
|
2402
|
+
this.guard.array(values.length + 1);
|
|
2403
|
+
this.guard.allocate(1);
|
|
2404
|
+
values.push(value2);
|
|
2405
|
+
value2 = "";
|
|
2406
|
+
if (this.take() === "}") return { type: "strings", values };
|
|
2407
|
+
} else {
|
|
2408
|
+
const item = this.parseSetCharacter(start);
|
|
2409
|
+
this.guard.allocate(item.length);
|
|
2410
|
+
value2 += item;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
this.fail("Unterminated class string", start);
|
|
2414
|
+
}
|
|
2415
|
+
if (this.peek() === "\\") return this.parseClassItem(start);
|
|
2416
|
+
const value = this.parseSetCharacter(start);
|
|
2417
|
+
this.guard.allocate(3 + value.length);
|
|
2418
|
+
return { type: "character", value };
|
|
2419
|
+
}
|
|
2420
|
+
parseSetCharacter(start) {
|
|
2421
|
+
if (this.peek() === "\\") {
|
|
2422
|
+
this.position++;
|
|
2423
|
+
const node = this.parseEscape(true, start);
|
|
2424
|
+
if (node.type !== "literal") this.fail("Class strings require literal characters", start);
|
|
2425
|
+
return node.value;
|
|
2426
|
+
}
|
|
2427
|
+
const character = this.takeCharacter();
|
|
2428
|
+
if (!character || "()[]{}/-|".includes(character) || "!#$%&*+,.:;<=>?@^`~".includes(character) && this.peek() === character)
|
|
2429
|
+
this.fail("Invalid character in Unicode set", start);
|
|
2430
|
+
return character;
|
|
2250
2431
|
}
|
|
2251
2432
|
parseEscape(inCharacterClass, start) {
|
|
2252
2433
|
if (this.atEnd()) {
|
|
2253
2434
|
this.fail("Trailing escape", start);
|
|
2254
2435
|
}
|
|
2255
2436
|
const escaped = this.take();
|
|
2256
|
-
if (escaped
|
|
2257
|
-
this.
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2437
|
+
if (escaped === "k") {
|
|
2438
|
+
this.totalCaptureCount ??= this.countAllCaptures();
|
|
2439
|
+
if (this.unicode || this.hasNamedCaptures) {
|
|
2440
|
+
if (inCharacterClass || this.take() !== "<") this.fail("Invalid named backreference", start);
|
|
2441
|
+
const name = this.parseGroupName(start);
|
|
2442
|
+
this.guard.allocate(3 + name.length);
|
|
2443
|
+
return { type: "namedBackreference", name };
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
if (isDecimalDigit2(escaped)) {
|
|
2447
|
+
if (!inCharacterClass && escaped !== "0") {
|
|
2448
|
+
let end = this.position;
|
|
2449
|
+
let index = Number(escaped);
|
|
2450
|
+
while (isDecimalDigit2(this.source[end] ?? "")) {
|
|
2451
|
+
this.guard.work(1);
|
|
2452
|
+
index = index * 10 + Number(this.source[end++]);
|
|
2453
|
+
}
|
|
2454
|
+
this.totalCaptureCount ??= this.countAllCaptures();
|
|
2455
|
+
if (index <= this.totalCaptureCount) {
|
|
2456
|
+
this.position = end;
|
|
2457
|
+
this.guard.allocate(3);
|
|
2458
|
+
return { type: "backreference", index };
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
if (this.unicode && (escaped !== "0" || isDecimalDigit2(this.peek())))
|
|
2462
|
+
this.fail("Invalid decimal escape", start);
|
|
2463
|
+
this.guard.allocate(4);
|
|
2464
|
+
if (escaped === "8" || escaped === "9") return { type: "literal", value: escaped };
|
|
2465
|
+
let code = Number(escaped);
|
|
2466
|
+
const maximum = escaped <= "3" ? 3 : 2;
|
|
2467
|
+
for (let digits = 1; digits < maximum && this.peek() >= "0" && this.peek() <= "7"; digits++) {
|
|
2468
|
+
code = code * 8 + Number(this.take());
|
|
2469
|
+
}
|
|
2470
|
+
return { type: "literal", value: String.fromCharCode(code) };
|
|
2471
|
+
}
|
|
2472
|
+
if (this.unicode && (escaped === "p" || escaped === "P")) {
|
|
2473
|
+
if (this.take() !== "{") this.fail("Invalid Unicode property escape", start);
|
|
2474
|
+
const begin = this.position;
|
|
2475
|
+
while (!this.atEnd() && this.peek() !== "}") {
|
|
2476
|
+
const character = this.take();
|
|
2477
|
+
if (!isDecimalDigit2(character) && !(character >= "a" && character <= "z") && !(character >= "A" && character <= "Z") && character !== "_" && character !== "=")
|
|
2478
|
+
this.fail("Invalid Unicode property escape", start);
|
|
2479
|
+
}
|
|
2480
|
+
this.guard.allocate(this.position - begin + 9);
|
|
2481
|
+
const value = this.source.slice(begin, this.position);
|
|
2482
|
+
if (this.take() !== "}") this.fail("Unterminated Unicode property escape", start);
|
|
2483
|
+
try {
|
|
2484
|
+
new RegExp(`\\${escaped}{${value}}`, this.unicodeSets ? "v" : "u");
|
|
2485
|
+
} catch {
|
|
2486
|
+
this.fail("Unknown Unicode property", start);
|
|
2487
|
+
}
|
|
2488
|
+
let strings = false;
|
|
2489
|
+
if (this.unicodeSets) {
|
|
2490
|
+
try {
|
|
2491
|
+
new RegExp(`\\p{${value}}`, "u");
|
|
2492
|
+
} catch {
|
|
2493
|
+
strings = true;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
this.guard.array(1);
|
|
2497
|
+
return { type: "characterClass", negated: false, items: [{ type: "property", value, negated: escaped === "P", ...strings ? { strings: true } : {} }] };
|
|
2261
2498
|
}
|
|
2262
2499
|
if (escaped === "x") {
|
|
2263
2500
|
this.guard.allocate(4);
|
|
2264
|
-
return { type: "literal", value: this.parseHexEscape(2, "hexadecimal", start) };
|
|
2501
|
+
return { type: "literal", value: this.parseHexEscape(2, "hexadecimal", start, this.unicode ? void 0 : "x") };
|
|
2265
2502
|
}
|
|
2266
2503
|
if (escaped === "u") {
|
|
2267
2504
|
this.guard.allocate(4);
|
|
2268
|
-
|
|
2505
|
+
if (this.unicode && this.peek() === "{") {
|
|
2506
|
+
this.position++;
|
|
2507
|
+
const begin = this.position;
|
|
2508
|
+
while (!this.atEnd() && this.peek() !== "}") this.position++;
|
|
2509
|
+
this.guard.allocate(this.position - begin);
|
|
2510
|
+
const digits = this.source.slice(begin, this.position);
|
|
2511
|
+
const point = Number.parseInt(digits, 16);
|
|
2512
|
+
if (this.take() !== "}" || digits.length === 0 || !allHexDigits(digits) || point > 1114111)
|
|
2513
|
+
this.fail("Invalid Unicode escape", start);
|
|
2514
|
+
return { type: "literal", value: String.fromCodePoint(point) };
|
|
2515
|
+
}
|
|
2516
|
+
let value = this.parseHexEscape(4, "Unicode", start, this.unicode ? void 0 : "u");
|
|
2517
|
+
if (this.unicode && value.charCodeAt(0) >= 55296 && value.charCodeAt(0) <= 56319 && this.source.startsWith("\\u", this.position)) {
|
|
2518
|
+
const digits = this.source.slice(this.position + 2, this.position + 6);
|
|
2519
|
+
const point = Number.parseInt(digits, 16);
|
|
2520
|
+
this.guard.work(digits.length);
|
|
2521
|
+
this.guard.allocate(digits.length);
|
|
2522
|
+
if (digits.length === 4 && allHexDigits(digits) && point >= 56320 && point <= 57343) {
|
|
2523
|
+
value += String.fromCharCode(point);
|
|
2524
|
+
this.position += 6;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
return { type: "literal", value };
|
|
2269
2528
|
}
|
|
2270
2529
|
this.guard.allocate(25);
|
|
2271
2530
|
const kinds = {
|
|
@@ -2296,20 +2555,101 @@ var RegexParser = class {
|
|
|
2296
2555
|
v: "\v",
|
|
2297
2556
|
"0": "\0"
|
|
2298
2557
|
};
|
|
2558
|
+
if (escaped === "c") {
|
|
2559
|
+
const letter = this.peek();
|
|
2560
|
+
this.guard.allocate(4);
|
|
2561
|
+
if (letter >= "a" && letter <= "z" || letter >= "A" && letter <= "Z" || !this.unicode && inCharacterClass && (isDecimalDigit2(letter) || letter === "_")) {
|
|
2562
|
+
this.position++;
|
|
2563
|
+
return { type: "literal", value: String.fromCharCode(letter.charCodeAt(0) % 32) };
|
|
2564
|
+
}
|
|
2565
|
+
if (this.unicode) this.fail("Invalid control escape", start);
|
|
2566
|
+
this.position--;
|
|
2567
|
+
return { type: "literal", value: "\\" };
|
|
2568
|
+
}
|
|
2569
|
+
if (this.unicode && controls[escaped] === void 0 && !"^$\\.*+?()[]{}|/".includes(escaped) && !(inCharacterClass && (escaped === "-" || this.unicodeSets && "!#$%&+,.:;<=>?@`~".includes(escaped))))
|
|
2570
|
+
this.fail("Invalid identity escape", start);
|
|
2299
2571
|
this.guard.allocate(4);
|
|
2300
2572
|
return { type: "literal", value: controls[escaped] ?? escaped };
|
|
2301
2573
|
}
|
|
2302
|
-
parseHexEscape(length, name, start) {
|
|
2574
|
+
parseHexEscape(length, name, start, identity) {
|
|
2303
2575
|
const end = this.position + length;
|
|
2304
2576
|
this.guard.allocate(Math.min(length, this.source.length - this.position));
|
|
2305
2577
|
this.guard.work(Math.min(length, this.source.length - this.position));
|
|
2306
2578
|
const digits = this.source.slice(this.position, end);
|
|
2307
2579
|
if (digits.length !== length || !allHexDigits(digits)) {
|
|
2580
|
+
if (identity !== void 0) return identity;
|
|
2308
2581
|
this.fail(`Invalid ${name} escape`, start);
|
|
2309
2582
|
}
|
|
2310
2583
|
this.position = end;
|
|
2311
2584
|
return String.fromCharCode(Number.parseInt(digits, 16));
|
|
2312
2585
|
}
|
|
2586
|
+
countAllCaptures() {
|
|
2587
|
+
let count = 0;
|
|
2588
|
+
let escaped = false;
|
|
2589
|
+
let characterClass = false;
|
|
2590
|
+
for (let index = 0; index < this.source.length; index++) {
|
|
2591
|
+
this.guard.work(1);
|
|
2592
|
+
const character = this.source[index];
|
|
2593
|
+
if (escaped) escaped = false;
|
|
2594
|
+
else if (character === "\\") escaped = true;
|
|
2595
|
+
else if (character === "[") characterClass = true;
|
|
2596
|
+
else if (character === "]") characterClass = false;
|
|
2597
|
+
else if (!characterClass && character === "(") {
|
|
2598
|
+
const named = this.source[index + 1] === "?" && this.source[index + 2] === "<" && this.source[index + 3] !== "=" && this.source[index + 3] !== "!";
|
|
2599
|
+
if (named) this.hasNamedCaptures = true;
|
|
2600
|
+
if (named || this.source[index + 1] !== "?") count++;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
return count;
|
|
2604
|
+
}
|
|
2605
|
+
parseGroupName(start) {
|
|
2606
|
+
let name = "";
|
|
2607
|
+
while (!this.atEnd() && this.peek() !== ">") {
|
|
2608
|
+
let character = this.take();
|
|
2609
|
+
if (character === "\\") {
|
|
2610
|
+
if (this.take() !== "u") this.fail("Invalid group name escape", start);
|
|
2611
|
+
if (this.peek() === "{") {
|
|
2612
|
+
this.position++;
|
|
2613
|
+
const begin = this.position;
|
|
2614
|
+
while (!this.atEnd() && this.peek() !== "}") this.position++;
|
|
2615
|
+
this.guard.allocate(this.position - begin);
|
|
2616
|
+
const digits = this.source.slice(begin, this.position);
|
|
2617
|
+
const point = Number.parseInt(digits, 16);
|
|
2618
|
+
if (this.take() !== "}" || digits.length === 0 || !allHexDigits(digits) || point > 1114111)
|
|
2619
|
+
this.fail("Invalid group name escape", start);
|
|
2620
|
+
character = String.fromCodePoint(point);
|
|
2621
|
+
} else character = this.parseHexEscape(4, "Unicode", start);
|
|
2622
|
+
}
|
|
2623
|
+
this.guard.allocate(character.length);
|
|
2624
|
+
name += character;
|
|
2625
|
+
}
|
|
2626
|
+
if (this.take() !== ">" || name.length === 0) this.fail("Invalid group name", start);
|
|
2627
|
+
let first = true;
|
|
2628
|
+
for (const character of name) {
|
|
2629
|
+
this.guard.work(1);
|
|
2630
|
+
if (!(first ? groupNameStart : groupNamePart).test(character)) this.fail("Invalid group name", start);
|
|
2631
|
+
first = false;
|
|
2632
|
+
}
|
|
2633
|
+
return name;
|
|
2634
|
+
}
|
|
2635
|
+
validateNamedGroups(node) {
|
|
2636
|
+
this.guard.work(1);
|
|
2637
|
+
this.guard.allocate(1);
|
|
2638
|
+
const names = /* @__PURE__ */ new Set();
|
|
2639
|
+
if (node.type === "namedBackreference" && !Object.hasOwn(this.namedGroups, node.name))
|
|
2640
|
+
this.fail("Unknown named backreference");
|
|
2641
|
+
if (node.type === "group" && node.name !== void 0) names.add(node.name);
|
|
2642
|
+
const children = node.type === "sequence" ? node.elements : node.type === "alternation" ? node.alternatives : node.type === "group" || node.type === "quantifier" || node.type === "lookahead" || node.type === "lookbehind" ? [node.body] : [];
|
|
2643
|
+
for (const child of children) {
|
|
2644
|
+
for (const name of this.validateNamedGroups(child)) {
|
|
2645
|
+
this.guard.work(1);
|
|
2646
|
+
if (names.has(name) && node.type !== "alternation") this.fail("Duplicate capture group name");
|
|
2647
|
+
this.guard.allocate(1);
|
|
2648
|
+
names.add(name);
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
return names;
|
|
2652
|
+
}
|
|
2313
2653
|
parseQuantifier() {
|
|
2314
2654
|
const character = this.peek();
|
|
2315
2655
|
if (character === "*") {
|
|
@@ -2339,18 +2679,29 @@ var RegexParser = class {
|
|
|
2339
2679
|
}
|
|
2340
2680
|
if (this.peek() === "}") {
|
|
2341
2681
|
this.position += 1;
|
|
2682
|
+
if (!Number.isSafeInteger(min)) this.fail("Quantifier is too large", start);
|
|
2342
2683
|
this.guard.allocate(3);
|
|
2343
2684
|
return { min, max: min };
|
|
2344
2685
|
}
|
|
2345
2686
|
if (this.peek() !== ",") {
|
|
2687
|
+
if (!this.unicode) {
|
|
2688
|
+
this.position = start;
|
|
2689
|
+
return void 0;
|
|
2690
|
+
}
|
|
2346
2691
|
this.fail("Invalid quantifier", start);
|
|
2347
2692
|
}
|
|
2348
2693
|
this.position += 1;
|
|
2349
2694
|
const max = this.parseDecimal();
|
|
2350
2695
|
if (this.peek() !== "}") {
|
|
2696
|
+
if (!this.unicode) {
|
|
2697
|
+
this.position = start;
|
|
2698
|
+
return void 0;
|
|
2699
|
+
}
|
|
2351
2700
|
this.fail("Unterminated quantifier", start);
|
|
2352
2701
|
}
|
|
2353
2702
|
this.position += 1;
|
|
2703
|
+
if (!Number.isSafeInteger(min) || max !== void 0 && !Number.isSafeInteger(max))
|
|
2704
|
+
this.fail("Quantifier is too large", start);
|
|
2354
2705
|
if (max !== void 0 && min > max) {
|
|
2355
2706
|
this.fail("Quantifier range is out of order", start);
|
|
2356
2707
|
}
|
|
@@ -2367,11 +2718,7 @@ var RegexParser = class {
|
|
|
2367
2718
|
}
|
|
2368
2719
|
this.guard.allocate(this.position - start);
|
|
2369
2720
|
this.guard.work(this.position - start);
|
|
2370
|
-
|
|
2371
|
-
if (!Number.isSafeInteger(value)) {
|
|
2372
|
-
this.fail("Quantifier is too large", start);
|
|
2373
|
-
}
|
|
2374
|
-
return value;
|
|
2721
|
+
return Number(this.source.slice(start, this.position));
|
|
2375
2722
|
}
|
|
2376
2723
|
peek() {
|
|
2377
2724
|
return this.source[this.position] ?? "";
|
|
@@ -2381,6 +2728,12 @@ var RegexParser = class {
|
|
|
2381
2728
|
this.position += 1;
|
|
2382
2729
|
return character;
|
|
2383
2730
|
}
|
|
2731
|
+
takeCharacter() {
|
|
2732
|
+
if (!this.unicode || this.atEnd()) return this.take();
|
|
2733
|
+
const character = String.fromCodePoint(this.source.codePointAt(this.position));
|
|
2734
|
+
this.position += character.length;
|
|
2735
|
+
return character;
|
|
2736
|
+
}
|
|
2384
2737
|
atEnd() {
|
|
2385
2738
|
return this.position >= this.source.length;
|
|
2386
2739
|
}
|
|
@@ -2391,16 +2744,24 @@ var RegexParser = class {
|
|
|
2391
2744
|
function parseFlags(flags, guard) {
|
|
2392
2745
|
guard.allocate(10);
|
|
2393
2746
|
const parsed = {
|
|
2747
|
+
hasIndices: false,
|
|
2394
2748
|
global: false,
|
|
2749
|
+
sticky: false,
|
|
2750
|
+
unicode: false,
|
|
2751
|
+
unicodeSets: false,
|
|
2395
2752
|
ignoreCase: false,
|
|
2396
2753
|
multiline: false,
|
|
2397
2754
|
dotAll: false
|
|
2398
2755
|
};
|
|
2399
2756
|
const names = {
|
|
2757
|
+
d: "hasIndices",
|
|
2400
2758
|
g: "global",
|
|
2401
2759
|
i: "ignoreCase",
|
|
2402
2760
|
m: "multiline",
|
|
2403
|
-
s: "dotAll"
|
|
2761
|
+
s: "dotAll",
|
|
2762
|
+
y: "sticky",
|
|
2763
|
+
u: "unicode",
|
|
2764
|
+
v: "unicodeSets"
|
|
2404
2765
|
};
|
|
2405
2766
|
for (let position = 0; position < flags.length; position += 1) {
|
|
2406
2767
|
guard.work(1);
|
|
@@ -2414,6 +2775,7 @@ function parseFlags(flags, guard) {
|
|
|
2414
2775
|
}
|
|
2415
2776
|
parsed[name] = true;
|
|
2416
2777
|
}
|
|
2778
|
+
if (parsed.unicode && parsed.unicodeSets) throw new SyntaxError("Unicode flags u and v cannot be combined");
|
|
2417
2779
|
return parsed;
|
|
2418
2780
|
}
|
|
2419
2781
|
function isDecimalDigit2(character) {
|
|
@@ -5467,6 +5829,7 @@ function findImportMetaAssignmentInNode(node) {
|
|
|
5467
5829
|
case "BooleanLiteral":
|
|
5468
5830
|
case "NullLiteral":
|
|
5469
5831
|
case "NumericLiteral":
|
|
5832
|
+
case "BigIntLiteral":
|
|
5470
5833
|
case "StringLiteral":
|
|
5471
5834
|
case "ThisExpression":
|
|
5472
5835
|
case "RegexLiteral":
|
|
@@ -5545,6 +5908,12 @@ function isYieldArgumentTerminator(value) {
|
|
|
5545
5908
|
return value === ";" || value === "}" || value === ")" || value === "]" || value === ",";
|
|
5546
5909
|
}
|
|
5547
5910
|
function createNumericLiteral(token) {
|
|
5911
|
+
if (token.value.endsWith("n")) return {
|
|
5912
|
+
type: "BigIntLiteral",
|
|
5913
|
+
raw: token.value,
|
|
5914
|
+
value: token.value.slice(0, -1).replaceAll("_", ""),
|
|
5915
|
+
span: createTokenSpan(token)
|
|
5916
|
+
};
|
|
5548
5917
|
return {
|
|
5549
5918
|
type: "NumericLiteral",
|
|
5550
5919
|
raw: token.value,
|
|
@@ -6723,9 +7092,13 @@ function isSandboxRegExpIterator(value) {
|
|
|
6723
7092
|
return typeof value === "object" && value !== null && states2.has(value);
|
|
6724
7093
|
}
|
|
6725
7094
|
function restoreSandboxRegExpIterator(state, target = /* @__PURE__ */ Object.create(null)) {
|
|
7095
|
+
if ((state.global !== void 0 || state.unicode !== void 0) && (typeof state.global !== "boolean" || typeof state.unicode !== "boolean"))
|
|
7096
|
+
throw new TypeError("Invalid RegExp iterator modes.");
|
|
7097
|
+
if (state.matcher !== void 0 && (state.matcher === null || typeof state.matcher !== "object"))
|
|
7098
|
+
throw new TypeError("Invalid RegExp iterator matcher.");
|
|
6726
7099
|
if (!state.exhausted && (state.matcher === void 0 || state.input === void 0))
|
|
6727
7100
|
throw new TypeError("A live RegExp iterator requires its matcher and input.");
|
|
6728
|
-
states2.set(target, state.exhausted ? { matcher: void 0, input: void 0, exhausted: true } : { ...state });
|
|
7101
|
+
states2.set(target, state.exhausted ? { ...state, matcher: void 0, input: void 0, exhausted: true } : { ...state });
|
|
6729
7102
|
return target;
|
|
6730
7103
|
}
|
|
6731
7104
|
function regexpIteratorState(value) {
|
|
@@ -6741,15 +7114,17 @@ var numberValue = Number.prototype.valueOf;
|
|
|
6741
7114
|
var stringValue = String.prototype.valueOf;
|
|
6742
7115
|
var booleanValue = Boolean.prototype.valueOf;
|
|
6743
7116
|
var symbolValue = Symbol.prototype.valueOf;
|
|
7117
|
+
var bigintValue = BigInt.prototype.valueOf;
|
|
6744
7118
|
function nativeBoxedValue(value) {
|
|
6745
7119
|
if (types3.isNumberObject(value)) return Reflect.apply(numberValue, value, []);
|
|
6746
7120
|
if (types3.isStringObject(value)) return Reflect.apply(stringValue, value, []);
|
|
6747
7121
|
if (types3.isBooleanObject(value)) return Reflect.apply(booleanValue, value, []);
|
|
6748
7122
|
if (types3.isSymbolObject(value)) return Reflect.apply(symbolValue, value, []);
|
|
7123
|
+
if (types3.isBigIntObject(value)) return Reflect.apply(bigintValue, value, []);
|
|
6749
7124
|
return void 0;
|
|
6750
7125
|
}
|
|
6751
7126
|
function createSandboxBox(value) {
|
|
6752
|
-
if (typeof value !== "number" && typeof value !== "string" && typeof value !== "boolean" && typeof value !== "symbol")
|
|
7127
|
+
if (typeof value !== "number" && typeof value !== "bigint" && typeof value !== "string" && typeof value !== "boolean" && typeof value !== "symbol")
|
|
6753
7128
|
throw new TypeError("Invalid boxed primitive payload.");
|
|
6754
7129
|
const box = Object(value);
|
|
6755
7130
|
Object.setPrototypeOf(box, null);
|
|
@@ -7244,6 +7619,18 @@ async function flushPromiseJobs() {
|
|
|
7244
7619
|
// packages/safe-js/src/interp/promise-replay.ts
|
|
7245
7620
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
7246
7621
|
|
|
7622
|
+
// packages/safe-js/src/snapshot/bigint.ts
|
|
7623
|
+
function validateBigIntData(value) {
|
|
7624
|
+
if (typeof value !== "string" || value.length === 0) throw new TypeError("Invalid BigInt snapshot value.");
|
|
7625
|
+
if (value === "0") return;
|
|
7626
|
+
const start = value[0] === "-" ? 1 : 0;
|
|
7627
|
+
if (start === value.length || value[start] === "0") throw new TypeError("Invalid BigInt snapshot value.");
|
|
7628
|
+
for (let index = start; index < value.length; index++) {
|
|
7629
|
+
const code = value.charCodeAt(index);
|
|
7630
|
+
if (code < 48 || code > 57) throw new TypeError("Invalid BigInt snapshot value.");
|
|
7631
|
+
}
|
|
7632
|
+
}
|
|
7633
|
+
|
|
7247
7634
|
// packages/safe-js/src/interp/symbols.ts
|
|
7248
7635
|
var wellKnownSymbols = Object.freeze({
|
|
7249
7636
|
iterator: Symbol.iterator,
|
|
@@ -7634,6 +8021,9 @@ function getSandboxPrototype(value, budget) {
|
|
|
7634
8021
|
function hasExplicitSandboxPrototype(value) {
|
|
7635
8022
|
return prototypes.has(value);
|
|
7636
8023
|
}
|
|
8024
|
+
function hasNullObjectPrototype(value) {
|
|
8025
|
+
return prototypes.get(value) === null && !Array.isArray(value) && !isSandboxClosure(value) && !isSandboxRegex(value);
|
|
8026
|
+
}
|
|
7637
8027
|
function getSandboxPropertyDescriptor(value, key, budget) {
|
|
7638
8028
|
const hostProperties = isSandboxClosure(value) ? value.properties : void 0;
|
|
7639
8029
|
if (isSandboxClosure(value) && !isGuestClosure(value))
|
|
@@ -7715,7 +8105,7 @@ function hasGuestObjectState(value) {
|
|
|
7715
8105
|
const intrinsicUnchanged = intrinsicConstructors.get(value);
|
|
7716
8106
|
if (intrinsicUnchanged !== void 0) return !intrinsicUnchanged();
|
|
7717
8107
|
if (isLiveCapability(value)) return true;
|
|
7718
|
-
if (functionProperties.has(value) || prototypes.has(value)) return true;
|
|
8108
|
+
if (functionProperties.has(value) || prototypes.has(value) && !hasNullObjectPrototype(value)) return true;
|
|
7719
8109
|
if (isSandboxBox(value) || isSandboxDate(value)) return false;
|
|
7720
8110
|
return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
|
|
7721
8111
|
(descriptor) => !descriptor.enumerable || !descriptor.configurable || !descriptor.writable
|
|
@@ -7910,6 +8300,7 @@ function createDumpFile(snapshot) {
|
|
|
7910
8300
|
return dumped;
|
|
7911
8301
|
}
|
|
7912
8302
|
function serializeDumpValue(value, path, state) {
|
|
8303
|
+
if (typeof value === "bigint") return { kind: "bigint", value: String(value) };
|
|
7913
8304
|
if (typeof value === "symbol") return serializeSymbol(value, state.heapIds, state.heap);
|
|
7914
8305
|
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
7915
8306
|
return value;
|
|
@@ -7956,11 +8347,14 @@ function serializeHeapReference(value, path, state) {
|
|
|
7956
8347
|
if (isSandboxRegExpIterator(value)) {
|
|
7957
8348
|
const snapshot = regexpIteratorState(value);
|
|
7958
8349
|
const matcher = snapshot.matcher;
|
|
8350
|
+
const serializedMatcher = snapshot.global === void 0 && isSandboxRegex(matcher) ? { kind: "regex", source: matcher.source, flags: matcher.flags, lastIndex: Number(matcher.lastIndex) } : serializeDumpValue(matcher, `${path}.<matcher>`, state);
|
|
8351
|
+
if (serializedMatcher === SKIP_VALUE) throw new TypeError("Unsupported RegExp iterator matcher in public dump.");
|
|
7959
8352
|
const entries = /* @__PURE__ */ Object.create(null);
|
|
7960
8353
|
state.heap[String(id)] = {
|
|
7961
8354
|
kind: "regexp-iterator",
|
|
7962
8355
|
exhausted: snapshot.exhausted,
|
|
7963
|
-
matcher:
|
|
8356
|
+
matcher: serializedMatcher,
|
|
8357
|
+
...snapshot.global === void 0 ? {} : { global: snapshot.global, unicode: snapshot.unicode },
|
|
7964
8358
|
input: snapshot.input ?? { kind: "undefined" },
|
|
7965
8359
|
entries,
|
|
7966
8360
|
symbolEntries: serializeSymbolProperties(value, (entry) => {
|
|
@@ -8033,6 +8427,7 @@ function serializeHeapReference(value, path, state) {
|
|
|
8033
8427
|
});
|
|
8034
8428
|
state.heap[String(id)] = {
|
|
8035
8429
|
kind: "object",
|
|
8430
|
+
...hasNullObjectPrototype(value) ? { sandboxNullPrototype: true } : {},
|
|
8036
8431
|
entries: serializeObjectEntries(value, path, state),
|
|
8037
8432
|
...symbolEntries.length === 0 ? {} : { symbolEntries },
|
|
8038
8433
|
...errorType === void 0 ? {} : { errorType }
|
|
@@ -8066,7 +8461,7 @@ function indexHeapContainers(snapshot) {
|
|
|
8066
8461
|
const heapIds = /* @__PURE__ */ new Map();
|
|
8067
8462
|
let nextId = 1;
|
|
8068
8463
|
for (const [value, stat2] of stats.entries()) {
|
|
8069
|
-
if (stat2.count > 1 || stat2.cyclic || ownSerializableSymbolKeys(value).length > 0 || isSandboxBox(value) || isSandboxRegExpIterator(value) || isSandboxRegex(value) && hasCustomRegexProperties(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
|
|
8464
|
+
if (stat2.count > 1 || stat2.cyclic || hasNullObjectPrototype(value) || ownSerializableSymbolKeys(value).length > 0 || isSandboxBox(value) || isSandboxRegExpIterator(value) || isSandboxRegex(value) && hasCustomRegexProperties(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
|
|
8070
8465
|
heapIds.set(value, nextId);
|
|
8071
8466
|
nextId += 1;
|
|
8072
8467
|
}
|
|
@@ -8252,6 +8647,8 @@ function validateDumpHeap(root, state) {
|
|
|
8252
8647
|
continue;
|
|
8253
8648
|
}
|
|
8254
8649
|
if (entry.kind === "object") {
|
|
8650
|
+
if (Object.hasOwn(entry, "sandboxNullPrototype") && entry.sandboxNullPrototype !== true)
|
|
8651
|
+
fail("invalidValue", `${path}.sandboxNullPrototype`, "invalid object prototype");
|
|
8255
8652
|
requireRecord(entry.entries, `${path}.entries`);
|
|
8256
8653
|
continue;
|
|
8257
8654
|
}
|
|
@@ -8335,6 +8732,14 @@ function validateValue(value, path, depth, state) {
|
|
|
8335
8732
|
}
|
|
8336
8733
|
function validateTaggedValue(record2, path, state) {
|
|
8337
8734
|
switch (record2.kind) {
|
|
8735
|
+
case "bigint":
|
|
8736
|
+
requireString(record2.value, `${path}.value`, state.limits);
|
|
8737
|
+
try {
|
|
8738
|
+
validateBigIntData(record2.value);
|
|
8739
|
+
} catch {
|
|
8740
|
+
fail("invalidValue", `${path}.value`, "invalid BigInt value");
|
|
8741
|
+
}
|
|
8742
|
+
return;
|
|
8338
8743
|
case "undefined":
|
|
8339
8744
|
return;
|
|
8340
8745
|
case "number":
|
|
@@ -8372,7 +8777,11 @@ function validateTaggedValue(record2, path, state) {
|
|
|
8372
8777
|
return;
|
|
8373
8778
|
case "array":
|
|
8374
8779
|
case "arguments":
|
|
8780
|
+
return;
|
|
8375
8781
|
case "object":
|
|
8782
|
+
if (Object.hasOwn(record2, "sandboxNullPrototype") && record2.sandboxNullPrototype !== true)
|
|
8783
|
+
fail("invalidValue", `${path}.sandboxNullPrototype`, "invalid object prototype");
|
|
8784
|
+
return;
|
|
8376
8785
|
case "map":
|
|
8377
8786
|
case "set":
|
|
8378
8787
|
case "collection-iterator":
|
|
@@ -8442,6 +8851,8 @@ function validateHeapValue(value, path, state, heap) {
|
|
|
8442
8851
|
}
|
|
8443
8852
|
if (record2.kind === "set") requireArray(record2.values, `${path}.values`, state);
|
|
8444
8853
|
if (record2.kind === "regexp-iterator") {
|
|
8854
|
+
if ((record2.global !== void 0 || record2.unicode !== void 0) && (typeof record2.global !== "boolean" || typeof record2.unicode !== "boolean"))
|
|
8855
|
+
fail("invalidValue", path, "invalid RegExp iterator modes");
|
|
8445
8856
|
if (typeof record2.exhausted !== "boolean") fail("invalidValue", `${path}.exhausted`, "invalid iterator exhaustion");
|
|
8446
8857
|
if (!Object.hasOwn(record2, "matcher") || !Object.hasOwn(record2, "input")) fail("invalidValue", path, "missing RegExp iterator state");
|
|
8447
8858
|
requireRecord(record2.entries, `${path}.entries`);
|
|
@@ -8495,6 +8906,14 @@ function validateBoxedRecord(record2, path, heap) {
|
|
|
8495
8906
|
const value = record2.value;
|
|
8496
8907
|
if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") return;
|
|
8497
8908
|
const number = requireRecord(value, `${path}.value`);
|
|
8909
|
+
if (number.kind === "bigint") {
|
|
8910
|
+
try {
|
|
8911
|
+
validateBigIntData(number.value);
|
|
8912
|
+
} catch {
|
|
8913
|
+
fail("invalidValue", `${path}.value`, "invalid boxed BigInt payload");
|
|
8914
|
+
}
|
|
8915
|
+
return;
|
|
8916
|
+
}
|
|
8498
8917
|
if (number.kind === "ref") {
|
|
8499
8918
|
const id = requireSafeInteger(number.id, `${path}.value.id`, 1);
|
|
8500
8919
|
const target = requireRecord(heap[String(id)], `${path}.value`);
|
|
@@ -9290,15 +9709,17 @@ async function withRunResources(signal, execute) {
|
|
|
9290
9709
|
|
|
9291
9710
|
// packages/safe-js/src/interp/regex/engine.ts
|
|
9292
9711
|
function matchRegex(pattern, input, lastIndex = 0) {
|
|
9293
|
-
const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
|
|
9712
|
+
const startIndex = pattern.flags.global || pattern.flags.sticky ? normalizeLastIndex(lastIndex) : 0;
|
|
9294
9713
|
return matchRegexFrom(pattern, input, startIndex);
|
|
9295
9714
|
}
|
|
9296
9715
|
function matchRegexFrom(pattern, input, startIndex) {
|
|
9297
9716
|
if (startIndex > input.length) {
|
|
9298
9717
|
return null;
|
|
9299
9718
|
}
|
|
9300
|
-
|
|
9301
|
-
|
|
9719
|
+
const unicode = pattern.flags.unicode || pattern.flags.unicodeSets;
|
|
9720
|
+
if (unicode && startIndex > 0 && startIndex < input.length && input.charCodeAt(startIndex) >= 56320 && input.charCodeAt(startIndex) <= 57343 && input.charCodeAt(startIndex - 1) >= 55296 && input.charCodeAt(startIndex - 1) <= 56319) startIndex--;
|
|
9721
|
+
for (let attempt = startIndex; attempt <= input.length; attempt = advanceStringIndex(input, attempt, unicode)) {
|
|
9722
|
+
const context = { input, flags: pattern.flags, groups: pattern.groups, direction: 1, work: { steps: 0 } };
|
|
9302
9723
|
charge(context);
|
|
9303
9724
|
const initialState = {
|
|
9304
9725
|
position: attempt,
|
|
@@ -9306,25 +9727,59 @@ function matchRegexFrom(pattern, input, startIndex) {
|
|
|
9306
9727
|
};
|
|
9307
9728
|
const result = matchNode(pattern.body, initialState, context).next();
|
|
9308
9729
|
if (!result.done) {
|
|
9309
|
-
return toRegexMatch(input, attempt, result.value);
|
|
9730
|
+
return toRegexMatch(input, attempt, result.value, pattern.flags.hasIndices, pattern.groups);
|
|
9310
9731
|
}
|
|
9732
|
+
if (pattern.flags.sticky) break;
|
|
9311
9733
|
}
|
|
9312
9734
|
return null;
|
|
9313
9735
|
}
|
|
9314
9736
|
function* matchNode(node, state, context) {
|
|
9315
9737
|
charge(context);
|
|
9738
|
+
const unicode = context.flags.unicode || context.flags.unicodeSets;
|
|
9739
|
+
const character = readCharacter(context.input, state.position, context.direction, unicode);
|
|
9316
9740
|
switch (node.type) {
|
|
9317
9741
|
case "empty":
|
|
9318
9742
|
yield state;
|
|
9319
9743
|
return;
|
|
9320
9744
|
case "literal":
|
|
9321
|
-
if (charactersEqual(
|
|
9322
|
-
yield { ...state, position: state.position +
|
|
9745
|
+
if (charactersEqual(character, node.value, context.flags.ignoreCase, unicode)) {
|
|
9746
|
+
yield { ...state, position: state.position + context.direction * character.length };
|
|
9323
9747
|
}
|
|
9324
9748
|
return;
|
|
9749
|
+
case "backreference":
|
|
9750
|
+
case "namedBackreference": {
|
|
9751
|
+
let capture;
|
|
9752
|
+
if (node.type === "backreference") capture = state.captures[node.index - 1];
|
|
9753
|
+
else {
|
|
9754
|
+
for (const index of context.groups?.[node.name] ?? []) {
|
|
9755
|
+
charge(context);
|
|
9756
|
+
if (state.captures[index - 1] !== void 0) {
|
|
9757
|
+
capture = state.captures[index - 1];
|
|
9758
|
+
break;
|
|
9759
|
+
}
|
|
9760
|
+
}
|
|
9761
|
+
}
|
|
9762
|
+
if (capture === void 0) {
|
|
9763
|
+
yield state;
|
|
9764
|
+
return;
|
|
9765
|
+
}
|
|
9766
|
+
let position = state.position;
|
|
9767
|
+
let reference = context.direction === 1 ? capture.start : capture.end;
|
|
9768
|
+
const end = context.direction === 1 ? capture.end : capture.start;
|
|
9769
|
+
while (reference !== end) {
|
|
9770
|
+
charge(context);
|
|
9771
|
+
const expected = readCharacter(context.input, reference, context.direction, unicode);
|
|
9772
|
+
const actual = readCharacter(context.input, position, context.direction, unicode);
|
|
9773
|
+
if (!charactersEqual(actual, expected, context.flags.ignoreCase, unicode)) return;
|
|
9774
|
+
reference += context.direction * expected.length;
|
|
9775
|
+
position += context.direction * actual.length;
|
|
9776
|
+
}
|
|
9777
|
+
yield { ...state, position };
|
|
9778
|
+
return;
|
|
9779
|
+
}
|
|
9325
9780
|
case "dot":
|
|
9326
|
-
if (
|
|
9327
|
-
yield { ...state, position: state.position +
|
|
9781
|
+
if (character !== void 0 && (context.flags.dotAll || !isLineTerminator(character))) {
|
|
9782
|
+
yield { ...state, position: state.position + context.direction * character.length };
|
|
9328
9783
|
}
|
|
9329
9784
|
return;
|
|
9330
9785
|
case "anchor":
|
|
@@ -9333,17 +9788,24 @@ function* matchNode(node, state, context) {
|
|
|
9333
9788
|
}
|
|
9334
9789
|
return;
|
|
9335
9790
|
case "wordBoundary": {
|
|
9336
|
-
const previousWord = state.position > 0 &&
|
|
9337
|
-
const nextWord = state.position < context.input.length &&
|
|
9791
|
+
const previousWord = state.position > 0 && matchesCharacterClassItem(context.input[state.position - 1], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, unicode);
|
|
9792
|
+
const nextWord = state.position < context.input.length && matchesCharacterClassItem(context.input[state.position], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, unicode);
|
|
9338
9793
|
if (previousWord !== nextWord !== node.negated) {
|
|
9339
9794
|
yield state;
|
|
9340
9795
|
}
|
|
9341
9796
|
return;
|
|
9342
9797
|
}
|
|
9343
9798
|
case "characterClass": {
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9799
|
+
if (context.flags.unicodeSets) {
|
|
9800
|
+
const lengths = [...matchUnicodeSet(node, state.position, context)].sort((a, b) => b - a);
|
|
9801
|
+
for (const length of lengths) {
|
|
9802
|
+
charge(context);
|
|
9803
|
+
yield { ...state, position: state.position + context.direction * length };
|
|
9804
|
+
}
|
|
9805
|
+
return;
|
|
9806
|
+
}
|
|
9807
|
+
if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context)) {
|
|
9808
|
+
yield { ...state, position: state.position + context.direction * character.length };
|
|
9347
9809
|
}
|
|
9348
9810
|
return;
|
|
9349
9811
|
}
|
|
@@ -9355,14 +9817,30 @@ function* matchNode(node, state, context) {
|
|
|
9355
9817
|
yield* matchNode(alternative, cloneState(state), context);
|
|
9356
9818
|
}
|
|
9357
9819
|
return;
|
|
9820
|
+
case "lookahead":
|
|
9821
|
+
case "lookbehind": {
|
|
9822
|
+
const result = matchNode(node.body, cloneState(state), {
|
|
9823
|
+
...context,
|
|
9824
|
+
direction: node.type === "lookbehind" ? -1 : 1
|
|
9825
|
+
}).next();
|
|
9826
|
+
if (node.negated) {
|
|
9827
|
+
if (result.done) yield state;
|
|
9828
|
+
} else if (!result.done) {
|
|
9829
|
+
yield { position: state.position, captures: result.value.captures };
|
|
9830
|
+
}
|
|
9831
|
+
return;
|
|
9832
|
+
}
|
|
9358
9833
|
case "group":
|
|
9359
|
-
for (const result of matchNode(node.body, cloneState(state), context
|
|
9834
|
+
for (const result of matchNode(node.body, cloneState(state), node.modifiers === void 0 ? context : {
|
|
9835
|
+
...context,
|
|
9836
|
+
flags: { ...context.flags, ...node.modifiers }
|
|
9837
|
+
})) {
|
|
9360
9838
|
if (!node.capturing || node.index === void 0) {
|
|
9361
9839
|
yield result;
|
|
9362
9840
|
continue;
|
|
9363
9841
|
}
|
|
9364
9842
|
const captures = result.captures.slice();
|
|
9365
|
-
captures[node.index - 1] = { start: state.position, end: result.position };
|
|
9843
|
+
captures[node.index - 1] = { start: Math.min(state.position, result.position), end: Math.max(state.position, result.position) };
|
|
9366
9844
|
yield { position: result.position, captures };
|
|
9367
9845
|
}
|
|
9368
9846
|
return;
|
|
@@ -9376,7 +9854,8 @@ function* matchSequence(elements, index, state, context) {
|
|
|
9376
9854
|
yield state;
|
|
9377
9855
|
return;
|
|
9378
9856
|
}
|
|
9379
|
-
|
|
9857
|
+
const element = elements[context.direction === 1 ? index : elements.length - 1 - index];
|
|
9858
|
+
for (const result of matchNode(element, state, context)) {
|
|
9380
9859
|
yield* matchSequence(elements, index + 1, result, context);
|
|
9381
9860
|
}
|
|
9382
9861
|
}
|
|
@@ -9412,11 +9891,28 @@ function matchesAnchor(kind, position, context) {
|
|
|
9412
9891
|
}
|
|
9413
9892
|
return position === context.input.length || context.flags.multiline && position < context.input.length && isLineTerminator(context.input[position]);
|
|
9414
9893
|
}
|
|
9415
|
-
function matchesCharacterClass(character, items, negated,
|
|
9416
|
-
const matched = items.some((item) =>
|
|
9894
|
+
function matchesCharacterClass(character, items, negated, context) {
|
|
9895
|
+
const matched = items.some((item) => {
|
|
9896
|
+
if (context.flags.unicode) charge(context);
|
|
9897
|
+
return matchesCharacterClassItem(character, item, context.flags.ignoreCase, context.flags.unicode);
|
|
9898
|
+
});
|
|
9417
9899
|
return negated ? !matched : matched;
|
|
9418
9900
|
}
|
|
9419
|
-
function matchesCharacterClassItem(character, item, ignoreCase) {
|
|
9901
|
+
function matchesCharacterClassItem(character, item, ignoreCase, unicode, unicodeSets = false) {
|
|
9902
|
+
if (item.type === "strings" || item.type === "set") return false;
|
|
9903
|
+
if (unicode) {
|
|
9904
|
+
const hex = (value) => `\\u{${value.codePointAt(0).toString(16)}}`;
|
|
9905
|
+
let atom;
|
|
9906
|
+
if (item.type === "character") atom = hex(item.value);
|
|
9907
|
+
else if (item.type === "range") atom = `[${hex(item.from)}-${hex(item.to)}]`;
|
|
9908
|
+
else if (item.type === "property") atom = `\\${item.negated ? "P" : "p"}{${item.value}}`;
|
|
9909
|
+
else {
|
|
9910
|
+
const kind = item.kind === "digit" ? "d" : item.kind === "word" ? "w" : "s";
|
|
9911
|
+
atom = `\\${item.negated ? kind.toUpperCase() : kind}`;
|
|
9912
|
+
}
|
|
9913
|
+
return new RegExp(`^(?:${atom})$`, (ignoreCase ? "i" : "") + (unicodeSets ? "v" : "u")).test(character);
|
|
9914
|
+
}
|
|
9915
|
+
if (item.type === "property") return false;
|
|
9420
9916
|
if (item.type === "character") {
|
|
9421
9917
|
return charactersEqual(character, item.value, ignoreCase);
|
|
9422
9918
|
}
|
|
@@ -9430,22 +9926,102 @@ function matchesCharacterClassItem(character, item, ignoreCase) {
|
|
|
9430
9926
|
if (!ignoreCase) {
|
|
9431
9927
|
return false;
|
|
9432
9928
|
}
|
|
9433
|
-
|
|
9434
|
-
const foldedFrom = foldCharacter(item.from, true).charCodeAt(0);
|
|
9435
|
-
const foldedTo = foldCharacter(item.to, true).charCodeAt(0);
|
|
9436
|
-
return foldedCandidate >= foldedFrom && foldedCandidate <= foldedTo;
|
|
9929
|
+
return new RegExp(`^[\\u${from.toString(16).padStart(4, "0")}-\\u${to.toString(16).padStart(4, "0")}]$`, "i").test(character);
|
|
9437
9930
|
}
|
|
9438
9931
|
const matched = item.kind === "digit" ? isDigit(character) : item.kind === "word" ? isWordCharacter(character) : isSpaceCharacter(character);
|
|
9439
9932
|
return item.negated ? !matched : matched;
|
|
9440
9933
|
}
|
|
9441
|
-
function
|
|
9442
|
-
|
|
9934
|
+
function matchUnicodeSet(set, position, context) {
|
|
9935
|
+
charge(context);
|
|
9936
|
+
let lengths = /* @__PURE__ */ new Set();
|
|
9937
|
+
for (let index = 0; index < set.items.length; index++) {
|
|
9938
|
+
const next = matchUnicodeSetItem(set.items[index], position, context);
|
|
9939
|
+
if (index === 0) lengths = next;
|
|
9940
|
+
else if (set.operation === void 0) {
|
|
9941
|
+
for (const length of next) {
|
|
9942
|
+
charge(context);
|
|
9943
|
+
lengths.add(length);
|
|
9944
|
+
}
|
|
9945
|
+
} else {
|
|
9946
|
+
for (const length of lengths) {
|
|
9947
|
+
charge(context);
|
|
9948
|
+
if (set.operation === "intersection" ? !next.has(length) : next.has(length)) lengths.delete(length);
|
|
9949
|
+
}
|
|
9950
|
+
}
|
|
9951
|
+
}
|
|
9952
|
+
if (set.negated) {
|
|
9953
|
+
const character = readCharacter(context.input, position, context.direction, true);
|
|
9954
|
+
return new Set(character !== void 0 && !lengths.has(character.length) ? [character.length] : []);
|
|
9955
|
+
}
|
|
9956
|
+
return lengths;
|
|
9957
|
+
}
|
|
9958
|
+
function matchUnicodeSetItem(item, position, context) {
|
|
9959
|
+
charge(context);
|
|
9960
|
+
if (item.type === "set") return matchUnicodeSet(item.value, position, context);
|
|
9961
|
+
const lengths = /* @__PURE__ */ new Set();
|
|
9962
|
+
if (item.type === "strings") {
|
|
9963
|
+
for (const value of item.values) {
|
|
9964
|
+
charge(context);
|
|
9965
|
+
let reference = context.direction === 1 ? 0 : value.length;
|
|
9966
|
+
let cursor = position;
|
|
9967
|
+
const end = context.direction === 1 ? value.length : 0;
|
|
9968
|
+
while (reference !== end) {
|
|
9969
|
+
charge(context);
|
|
9970
|
+
const expected = readCharacter(value, reference, context.direction, true);
|
|
9971
|
+
const actual = readCharacter(context.input, cursor, context.direction, true);
|
|
9972
|
+
if (!charactersEqual(actual, expected, context.flags.ignoreCase, true)) break;
|
|
9973
|
+
reference += context.direction * expected.length;
|
|
9974
|
+
cursor += context.direction * actual.length;
|
|
9975
|
+
}
|
|
9976
|
+
if (reference === end) lengths.add(Math.abs(cursor - position));
|
|
9977
|
+
}
|
|
9978
|
+
return lengths;
|
|
9979
|
+
}
|
|
9980
|
+
if (item.type === "property" && item.strings) {
|
|
9981
|
+
const atom = `\\p{${item.value}}`;
|
|
9982
|
+
const flags = (context.flags.ignoreCase ? "i" : "") + "v";
|
|
9983
|
+
const matcher = new RegExp(context.direction === 1 ? atom : `(?<=(${atom}))`, flags + "y");
|
|
9984
|
+
matcher.lastIndex = position;
|
|
9985
|
+
const match = matcher.exec(context.input);
|
|
9986
|
+
if (match === null) return lengths;
|
|
9987
|
+
const longest = context.direction === 1 ? match[0] : match[1];
|
|
9988
|
+
const member = new RegExp(`^(?:${atom})$`, flags);
|
|
9989
|
+
let consumed = 0;
|
|
9990
|
+
while (consumed < longest.length) {
|
|
9991
|
+
charge(context);
|
|
9992
|
+
const cursor = context.direction === 1 ? consumed : longest.length - consumed;
|
|
9993
|
+
consumed += readCharacter(longest, cursor, context.direction, true).length;
|
|
9994
|
+
const candidate = context.direction === 1 ? longest.slice(0, consumed) : longest.slice(longest.length - consumed);
|
|
9995
|
+
if (member.test(candidate)) lengths.add(consumed);
|
|
9996
|
+
}
|
|
9997
|
+
return lengths;
|
|
9998
|
+
}
|
|
9999
|
+
const character = readCharacter(context.input, position, context.direction, true);
|
|
10000
|
+
if (character !== void 0 && matchesCharacterClassItem(character, item, context.flags.ignoreCase, true, true))
|
|
10001
|
+
lengths.add(character.length);
|
|
10002
|
+
return lengths;
|
|
10003
|
+
}
|
|
10004
|
+
function toRegexMatch(input, start, state, hasIndices, groups) {
|
|
10005
|
+
const match = {
|
|
9443
10006
|
index: start,
|
|
9444
10007
|
text: input.slice(start, state.position),
|
|
9445
10008
|
captures: state.captures.map(
|
|
9446
10009
|
(capture) => capture === void 0 ? void 0 : input.slice(capture.start, capture.end)
|
|
9447
10010
|
)
|
|
9448
10011
|
};
|
|
10012
|
+
if (hasIndices) {
|
|
10013
|
+
match.indices = [[start, state.position], ...state.captures.map((capture) => capture === void 0 ? void 0 : [capture.start, capture.end])];
|
|
10014
|
+
}
|
|
10015
|
+
if (groups !== void 0) {
|
|
10016
|
+
match.groups = /* @__PURE__ */ Object.create(null);
|
|
10017
|
+
if (hasIndices) match.indicesGroups = /* @__PURE__ */ Object.create(null);
|
|
10018
|
+
for (const [name, indices] of Object.entries(groups)) {
|
|
10019
|
+
const index = indices.find((index2) => state.captures[index2 - 1] !== void 0);
|
|
10020
|
+
match.groups[name] = index === void 0 ? void 0 : match.captures[index - 1];
|
|
10021
|
+
if (match.indicesGroups !== void 0) match.indicesGroups[name] = index === void 0 ? void 0 : match.indices[index];
|
|
10022
|
+
}
|
|
10023
|
+
}
|
|
10024
|
+
return match;
|
|
9449
10025
|
}
|
|
9450
10026
|
function cloneState(state) {
|
|
9451
10027
|
return { position: state.position, captures: state.captures.slice() };
|
|
@@ -9475,13 +10051,13 @@ function clearNodeCaptures(node, captures) {
|
|
|
9475
10051
|
}
|
|
9476
10052
|
return;
|
|
9477
10053
|
}
|
|
9478
|
-
if (node.type === "quantifier") {
|
|
10054
|
+
if (node.type === "quantifier" || node.type === "lookahead" || node.type === "lookbehind") {
|
|
9479
10055
|
clearNodeCaptures(node.body, captures);
|
|
9480
10056
|
}
|
|
9481
10057
|
}
|
|
9482
10058
|
function charge(context) {
|
|
9483
|
-
context.steps += 1;
|
|
9484
|
-
allocateRegexSteps(context.steps);
|
|
10059
|
+
context.work.steps += 1;
|
|
10060
|
+
allocateRegexSteps(context.work.steps);
|
|
9485
10061
|
}
|
|
9486
10062
|
function normalizeLastIndex(lastIndex) {
|
|
9487
10063
|
if (Number.isNaN(lastIndex) || lastIndex <= 0) {
|
|
@@ -9489,9 +10065,20 @@ function normalizeLastIndex(lastIndex) {
|
|
|
9489
10065
|
}
|
|
9490
10066
|
return Math.min(Math.floor(lastIndex), Number.MAX_SAFE_INTEGER);
|
|
9491
10067
|
}
|
|
9492
|
-
function charactersEqual(left, right, ignoreCase) {
|
|
10068
|
+
function charactersEqual(left, right, ignoreCase, unicode = false) {
|
|
10069
|
+
if (unicode && ignoreCase && left !== void 0)
|
|
10070
|
+
return new RegExp(`^\\u{${right.codePointAt(0).toString(16)}}$`, "iu").test(left);
|
|
9493
10071
|
return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
|
|
9494
10072
|
}
|
|
10073
|
+
function advanceStringIndex(input, index, unicode) {
|
|
10074
|
+
return index + (unicode && (input.codePointAt(index) ?? 0) > 65535 ? 2 : 1);
|
|
10075
|
+
}
|
|
10076
|
+
function readCharacter(input, position, direction, unicode) {
|
|
10077
|
+
let index = direction === 1 ? position : position - 1;
|
|
10078
|
+
if (index < 0 || index >= input.length) return void 0;
|
|
10079
|
+
if (unicode && direction === -1 && index > 0 && input.charCodeAt(index) >= 56320 && input.charCodeAt(index) <= 57343 && input.charCodeAt(index - 1) >= 55296 && input.charCodeAt(index - 1) <= 56319) index--;
|
|
10080
|
+
return unicode ? String.fromCodePoint(input.codePointAt(index)) : input[index];
|
|
10081
|
+
}
|
|
9495
10082
|
function foldCharacter(character, ignoreCase) {
|
|
9496
10083
|
if (!ignoreCase) {
|
|
9497
10084
|
return character;
|
|
@@ -9518,6 +10105,69 @@ function isLineTerminator(character) {
|
|
|
9518
10105
|
return character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029";
|
|
9519
10106
|
}
|
|
9520
10107
|
|
|
10108
|
+
// packages/safe-js/src/interp/bigint-operators.ts
|
|
10109
|
+
function bigIntOperation(operator, left, right, budget) {
|
|
10110
|
+
if (operator === ">>>") throw new TypeError("BigInts have no unsigned right shift.");
|
|
10111
|
+
if ((operator === "/" || operator === "%") && right === 0n) throw new RangeError("Division by zero.");
|
|
10112
|
+
if (operator === "**" && right < 0n) throw new RangeError("BigInt exponent must be nonnegative.");
|
|
10113
|
+
const leftSize = left.toString(16).length;
|
|
10114
|
+
const rightSize = right.toString(16).length;
|
|
10115
|
+
budget.visitNode(leftSize + rightSize);
|
|
10116
|
+
let size = Math.max(leftSize, rightSize) + 1;
|
|
10117
|
+
let work = leftSize + rightSize;
|
|
10118
|
+
if (operator === "*") {
|
|
10119
|
+
size = leftSize + rightSize;
|
|
10120
|
+
work = leftSize * rightSize;
|
|
10121
|
+
} else if (operator === "/" || operator === "%") {
|
|
10122
|
+
size = leftSize;
|
|
10123
|
+
work = leftSize * rightSize;
|
|
10124
|
+
} else if (operator === "**") {
|
|
10125
|
+
if (right === 0n) return 1n;
|
|
10126
|
+
if (left === 0n || left === 1n) return left;
|
|
10127
|
+
if (left === -1n) return right % 2n === 0n ? 1n : -1n;
|
|
10128
|
+
size = leftSize * Number(right);
|
|
10129
|
+
work = size * size;
|
|
10130
|
+
} else if (operator === "<<" || operator === ">>") {
|
|
10131
|
+
if (left === 0n) return 0n;
|
|
10132
|
+
const shift = operator === "<<" ? right : -right;
|
|
10133
|
+
size = shift > 0n ? leftSize + Math.ceil(Number(shift) / 4) : leftSize;
|
|
10134
|
+
work = size + rightSize;
|
|
10135
|
+
}
|
|
10136
|
+
if (!Number.isSafeInteger(size) || !Number.isSafeInteger(work))
|
|
10137
|
+
throw new SandboxError({ budget: "dataSize", current: Infinity, limit: Number.MAX_SAFE_INTEGER });
|
|
10138
|
+
budget.visitNode(work);
|
|
10139
|
+
const allocation = {};
|
|
10140
|
+
budget.setRetainedDataUsage(allocation, size);
|
|
10141
|
+
try {
|
|
10142
|
+
switch (operator) {
|
|
10143
|
+
case "+":
|
|
10144
|
+
return left + right;
|
|
10145
|
+
case "-":
|
|
10146
|
+
return left - right;
|
|
10147
|
+
case "*":
|
|
10148
|
+
return left * right;
|
|
10149
|
+
case "/":
|
|
10150
|
+
return left / right;
|
|
10151
|
+
case "%":
|
|
10152
|
+
return left % right;
|
|
10153
|
+
case "**":
|
|
10154
|
+
return left ** right;
|
|
10155
|
+
case "&":
|
|
10156
|
+
return left & right;
|
|
10157
|
+
case "|":
|
|
10158
|
+
return left | right;
|
|
10159
|
+
case "^":
|
|
10160
|
+
return left ^ right;
|
|
10161
|
+
case "<<":
|
|
10162
|
+
return left << right;
|
|
10163
|
+
case ">>":
|
|
10164
|
+
return left >> right;
|
|
10165
|
+
}
|
|
10166
|
+
} finally {
|
|
10167
|
+
budget.setRetainedDataUsage(allocation, 0);
|
|
10168
|
+
}
|
|
10169
|
+
}
|
|
10170
|
+
|
|
9521
10171
|
// packages/safe-js/src/interp/jobs.ts
|
|
9522
10172
|
import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
|
|
9523
10173
|
var activeJob = new AsyncLocalStorage4();
|
|
@@ -9693,7 +10343,7 @@ function callNumberMethod(value, methodName, args, budget, context) {
|
|
|
9693
10343
|
if (argument !== null && typeof argument === "object") {
|
|
9694
10344
|
return formatObjectArgument(value, methodName, argument, budget, context);
|
|
9695
10345
|
}
|
|
9696
|
-
return formatNumber(value, methodName, argument === void 0 ? void 0 :
|
|
10346
|
+
return formatNumber(value, methodName, argument === void 0 ? void 0 : +argument, budget);
|
|
9697
10347
|
}
|
|
9698
10348
|
async function formatObjectArgument(value, methodName, argument, budget, context) {
|
|
9699
10349
|
const retainedArgument = {};
|
|
@@ -10067,7 +10717,7 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, use
|
|
|
10067
10717
|
);
|
|
10068
10718
|
}
|
|
10069
10719
|
async function replaceRegex(value, regex, replacement, budget, callClosure, context) {
|
|
10070
|
-
if (hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget))
|
|
10720
|
+
if (getSandboxRegexPattern(regex).groups !== void 0 || hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget))
|
|
10071
10721
|
return regexReplace(value, regex, replacement, budget, callClosure, context);
|
|
10072
10722
|
if (regex.flags.includes("g")) regex.lastIndex = 0;
|
|
10073
10723
|
const cursor = regex.lastIndex;
|
|
@@ -10117,7 +10767,7 @@ async function regexReplace(input, regex, replacementInput, budget, callClosure,
|
|
|
10117
10767
|
input = void 0;
|
|
10118
10768
|
replacement = isSandboxClosure(replacementInput) ? replacementInput : await sandboxString(replacementInput, budget, context);
|
|
10119
10769
|
replacementInput = void 0;
|
|
10120
|
-
if (isSandboxRegex(regex) && !hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget)) {
|
|
10770
|
+
if (isSandboxRegex(regex) && getSandboxRegexPattern(regex).groups === void 0 && !hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget)) {
|
|
10121
10771
|
release();
|
|
10122
10772
|
return await replaceRegex(value, regex, replacement, budget, callClosure, context);
|
|
10123
10773
|
}
|
|
@@ -10332,7 +10982,7 @@ function splitNormalized(value, separator, limit, budget, parent) {
|
|
|
10332
10982
|
while (result2.length < limit) {
|
|
10333
10983
|
const match = executeRegex(splitter, value, Number(splitter.lastIndex));
|
|
10334
10984
|
if (match === null) break;
|
|
10335
|
-
if (match.text.length === 0) splitter.lastIndex = match.index
|
|
10985
|
+
if (match.text.length === 0) splitter.lastIndex = advanceStringIndex(value, match.index, splitter.flags.includes("u") || splitter.flags.includes("v"));
|
|
10336
10986
|
endedWithZeroWidthMatch = match.text.length === 0 && match.index === value.length;
|
|
10337
10987
|
if (match.text.length === 0 && (match.index === copiedThrough || match.index === value.length))
|
|
10338
10988
|
continue;
|
|
@@ -10491,7 +11141,7 @@ function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
|
|
|
10491
11141
|
return match?.index ?? -1;
|
|
10492
11142
|
}
|
|
10493
11143
|
if (methodName === "match" && !regex.flags.includes("g"))
|
|
10494
|
-
return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
|
|
11144
|
+
return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value, compilation.owner?.budget);
|
|
10495
11145
|
if (methodName === "match") regex.lastIndex = 0;
|
|
10496
11146
|
const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, normalizeLastIndex(lastIndex ?? Number(regex.lastIndex)), compilation) : regex;
|
|
10497
11147
|
if (methodName === "matchAll")
|
|
@@ -10507,7 +11157,7 @@ function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
|
|
|
10507
11157
|
budget?.allocateArrayLength(matches.length + 1);
|
|
10508
11158
|
matches.push(match);
|
|
10509
11159
|
lastIndex = match.index + match.text.length;
|
|
10510
|
-
if (all && match.text.length === 0) regex.lastIndex =
|
|
11160
|
+
if (all && match.text.length === 0) regex.lastIndex = lastIndex = advanceStringIndex(value, lastIndex, regex.flags.includes("u") || regex.flags.includes("v"));
|
|
10511
11161
|
} while (all);
|
|
10512
11162
|
return matches;
|
|
10513
11163
|
}
|
|
@@ -10516,10 +11166,10 @@ function splitString(value, separator, limit) {
|
|
|
10516
11166
|
return split.call(value, separator, limit);
|
|
10517
11167
|
}
|
|
10518
11168
|
function asNumber(value) {
|
|
10519
|
-
return
|
|
11169
|
+
return +value;
|
|
10520
11170
|
}
|
|
10521
11171
|
function asNumberOrUndefined(value) {
|
|
10522
|
-
return value === void 0 ? void 0 :
|
|
11172
|
+
return value === void 0 ? void 0 : +value;
|
|
10523
11173
|
}
|
|
10524
11174
|
function asStringOrUndefined(value) {
|
|
10525
11175
|
return value === void 0 ? void 0 : String(value);
|
|
@@ -10869,7 +11519,7 @@ function createObjectArrayGlobals(options) {
|
|
|
10869
11519
|
),
|
|
10870
11520
|
Number: createPrimitiveConstructor(
|
|
10871
11521
|
{
|
|
10872
|
-
call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
|
|
11522
|
+
call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context, true),
|
|
10873
11523
|
name: "Number",
|
|
10874
11524
|
properties: {
|
|
10875
11525
|
isFinite: createSandboxClosure({
|
|
@@ -13553,6 +14203,16 @@ var dispatchTable = {
|
|
|
13553
14203
|
ArrowFunctionExpression: evaluateArrowFunction,
|
|
13554
14204
|
AwaitExpression: evaluateAwait,
|
|
13555
14205
|
BinaryExpression: evaluateBinaryExpression,
|
|
14206
|
+
BigIntLiteral: async (node, context) => {
|
|
14207
|
+
const allocation = {};
|
|
14208
|
+
context.budget.visitNode(node.value.length);
|
|
14209
|
+
context.budget.setRetainedDataUsage(allocation, node.value.length);
|
|
14210
|
+
try {
|
|
14211
|
+
return { kind: "normal", hasValue: true, value: BigInt(node.value) };
|
|
14212
|
+
} finally {
|
|
14213
|
+
context.budget.setRetainedDataUsage(allocation, 0);
|
|
14214
|
+
}
|
|
14215
|
+
},
|
|
13556
14216
|
BlockStatement: evaluateBlockStatement,
|
|
13557
14217
|
BooleanLiteral: evaluatePrimitiveLiteral,
|
|
13558
14218
|
CallExpression: evaluateCallExpression,
|
|
@@ -15327,8 +15987,9 @@ async function evaluateIdentifierUpdateExpression(node, context) {
|
|
|
15327
15987
|
)
|
|
15328
15988
|
};
|
|
15329
15989
|
}
|
|
15330
|
-
const
|
|
15331
|
-
const
|
|
15990
|
+
const primitive = await toNumericPrimitive(binding.value, context);
|
|
15991
|
+
const current = typeof primitive === "bigint" ? primitive : toNumber(primitive);
|
|
15992
|
+
const next = typeof current === "bigint" ? bigIntOperation(node.operator === "++" ? "+" : "-", current, 1n, context.budget) : node.operator === "++" ? current + 1 : current - 1;
|
|
15332
15993
|
context.scope.assign(node.argument.name, next);
|
|
15333
15994
|
return {
|
|
15334
15995
|
kind: "normal",
|
|
@@ -15345,10 +16006,9 @@ async function evaluateMemberUpdateExpression(node, context) {
|
|
|
15345
16006
|
throw new TypeError("Cannot update properties of null or undefined.");
|
|
15346
16007
|
}
|
|
15347
16008
|
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
15348
|
-
const
|
|
15349
|
-
|
|
15350
|
-
);
|
|
15351
|
-
const next = node.operator === "++" ? current + 1 : current - 1;
|
|
16009
|
+
const primitive = await toNumericPrimitive(await getPropertyValue(member.object, property, context, member.superReceiver === void 0 ? member.object : member.superReceiver.value), context);
|
|
16010
|
+
const current = typeof primitive === "bigint" ? primitive : toNumber(primitive);
|
|
16011
|
+
const next = typeof current === "bigint" ? bigIntOperation(node.operator === "++" ? "+" : "-", current, 1n, context.budget) : node.operator === "++" ? current + 1 : current - 1;
|
|
15352
16012
|
if (member.superReceiver === void 0) await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
|
|
15353
16013
|
else await setSuperProperty(member.object, member.superReceiver.value, property, next, context);
|
|
15354
16014
|
return {
|
|
@@ -15382,7 +16042,7 @@ function getPropertyValue(target, property, context, receiver = target) {
|
|
|
15382
16042
|
if (descriptor !== void 0)
|
|
15383
16043
|
return readPropertyDescriptor(descriptor, receiver, createCoercionContext(context), true);
|
|
15384
16044
|
if (isSandboxRegExpIterator(target)) return getRegExpIteratorMember(property, context.budget);
|
|
15385
|
-
if (typeof target === "symbol") {
|
|
16045
|
+
if (typeof target === "symbol" || typeof target === "bigint") {
|
|
15386
16046
|
const prototype = getBoxedPrototype(target, context.budget);
|
|
15387
16047
|
return prototype === void 0 ? void 0 : getPropertyValue(prototype, property, context, receiver);
|
|
15388
16048
|
}
|
|
@@ -15563,6 +16223,7 @@ async function evaluateObjectPropertyKey(node, context) {
|
|
|
15563
16223
|
return evaluateMemberProperty(node.key, context);
|
|
15564
16224
|
}
|
|
15565
16225
|
function getStaticPropertyName(node) {
|
|
16226
|
+
if (node.type === "BigIntLiteral") return BigInt(node.value).toString();
|
|
15566
16227
|
if (node.type === "Identifier") {
|
|
15567
16228
|
return node.name;
|
|
15568
16229
|
}
|
|
@@ -15596,7 +16257,7 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
15596
16257
|
return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
|
|
15597
16258
|
if (Array.isArray(member.object) && hasExplicitSandboxPrototype(member.object))
|
|
15598
16259
|
return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
|
|
15599
|
-
if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean" || typeof member.object === "symbol") && getBoxedPrototype(member.object, context.budget) !== void 0) {
|
|
16260
|
+
if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "bigint" || typeof member.object === "boolean" || typeof member.object === "symbol") && getBoxedPrototype(member.object, context.budget) !== void 0) {
|
|
15600
16261
|
if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
|
|
15601
16262
|
if (typeof member.object === "string" && isStringMethodName(member.property))
|
|
15602
16263
|
return evaluateStringMethodCall(node, member.object, member.property, context);
|
|
@@ -15846,10 +16507,14 @@ async function applyUnaryOperator(operator, value, context) {
|
|
|
15846
16507
|
return void 0;
|
|
15847
16508
|
case "+":
|
|
15848
16509
|
return toNumber(await toNumericPrimitive(value, context));
|
|
15849
|
-
case "-":
|
|
15850
|
-
|
|
15851
|
-
|
|
15852
|
-
|
|
16510
|
+
case "-": {
|
|
16511
|
+
const primitive = await toNumericPrimitive(value, context);
|
|
16512
|
+
return typeof primitive === "bigint" ? bigIntOperation("-", 0n, primitive, context.budget) : -toNumber(primitive);
|
|
16513
|
+
}
|
|
16514
|
+
case "~": {
|
|
16515
|
+
const primitive = await toNumericPrimitive(value, context);
|
|
16516
|
+
return typeof primitive === "bigint" ? bigIntOperation("^", primitive, -1n, context.budget) : ~toNumber(primitive);
|
|
16517
|
+
}
|
|
15853
16518
|
}
|
|
15854
16519
|
}
|
|
15855
16520
|
function describeTypeofValue(value) {
|
|
@@ -15865,6 +16530,10 @@ function isTruthy(value) {
|
|
|
15865
16530
|
return Boolean(value);
|
|
15866
16531
|
}
|
|
15867
16532
|
function applyBinaryOperator(node, left, right, context) {
|
|
16533
|
+
if ((typeof left === "bigint" || typeof right === "bigint") && ["-", "*", "/", "%", "**", "&", "|", "^", "<<", ">>", ">>>"].includes(node.operator)) {
|
|
16534
|
+
if (typeof left !== "bigint" || typeof right !== "bigint") throw new TypeError("Cannot mix BigInt and other numeric types.");
|
|
16535
|
+
return bigIntOperation(node.operator, left, right, context.budget);
|
|
16536
|
+
}
|
|
15868
16537
|
switch (node.operator) {
|
|
15869
16538
|
case "+":
|
|
15870
16539
|
return applyAdditionOperator(left, right, context);
|
|
@@ -15983,6 +16652,10 @@ async function applyCompoundAssignmentOperator(operator, left, right, context) {
|
|
|
15983
16652
|
left = await toNumericPrimitive(left, context, operator === "+=" ? "default" : "number");
|
|
15984
16653
|
if (convertingObject) convertedLeft = left;
|
|
15985
16654
|
right = await toNumericPrimitive(right, context, operator === "+=" ? "default" : "number");
|
|
16655
|
+
if (operator !== "+=" && (typeof left === "bigint" || typeof right === "bigint")) {
|
|
16656
|
+
if (typeof left !== "bigint" || typeof right !== "bigint") throw new TypeError("Cannot mix BigInt and other numeric types.");
|
|
16657
|
+
return bigIntOperation(operator.slice(0, -1), left, right, context.budget);
|
|
16658
|
+
}
|
|
15986
16659
|
switch (operator) {
|
|
15987
16660
|
case "+=":
|
|
15988
16661
|
return applyAdditionOperator(left, right, context);
|
|
@@ -16019,6 +16692,10 @@ function applyAdditionOperator(left, right, context) {
|
|
|
16019
16692
|
if (typeof leftPrimitive === "string" || typeof rightPrimitive === "string") {
|
|
16020
16693
|
return context.budget.allocateString(toString(leftPrimitive) + toString(rightPrimitive));
|
|
16021
16694
|
}
|
|
16695
|
+
if (typeof leftPrimitive === "bigint" || typeof rightPrimitive === "bigint") {
|
|
16696
|
+
if (typeof leftPrimitive !== "bigint" || typeof rightPrimitive !== "bigint") throw new TypeError("Cannot mix BigInt and other numeric types.");
|
|
16697
|
+
return bigIntOperation("+", leftPrimitive, rightPrimitive, context.budget);
|
|
16698
|
+
}
|
|
16022
16699
|
return toNumber(leftPrimitive) + toNumber(rightPrimitive);
|
|
16023
16700
|
}
|
|
16024
16701
|
function compareRelational(left, right, operator) {
|
|
@@ -16036,8 +16713,9 @@ function compareRelational(left, right, operator) {
|
|
|
16036
16713
|
return leftPrimitive >= rightPrimitive;
|
|
16037
16714
|
}
|
|
16038
16715
|
}
|
|
16039
|
-
const
|
|
16040
|
-
const
|
|
16716
|
+
const hasBigInt = typeof leftPrimitive === "bigint" || typeof rightPrimitive === "bigint";
|
|
16717
|
+
const leftNumber = typeof leftPrimitive === "bigint" || hasBigInt && typeof leftPrimitive === "string" ? leftPrimitive : toNumber(leftPrimitive);
|
|
16718
|
+
const rightNumber = typeof rightPrimitive === "bigint" || hasBigInt && typeof rightPrimitive === "string" ? rightPrimitive : toNumber(rightPrimitive);
|
|
16041
16719
|
switch (operator) {
|
|
16042
16720
|
case "<":
|
|
16043
16721
|
return leftNumber < rightNumber;
|
|
@@ -16050,6 +16728,7 @@ function compareRelational(left, right, operator) {
|
|
|
16050
16728
|
}
|
|
16051
16729
|
}
|
|
16052
16730
|
function isLooselyEqual(left, right) {
|
|
16731
|
+
if (typeof left === "bigint" || typeof right === "bigint") return left == right;
|
|
16053
16732
|
const leftType = getCoercionType(left);
|
|
16054
16733
|
const rightType = getCoercionType(right);
|
|
16055
16734
|
if (leftType === rightType) {
|
|
@@ -16082,6 +16761,7 @@ function isPrimitiveCoercionType(type) {
|
|
|
16082
16761
|
return type !== "object";
|
|
16083
16762
|
}
|
|
16084
16763
|
function getCoercionType(value) {
|
|
16764
|
+
if (typeof value === "bigint") return "bigint";
|
|
16085
16765
|
if (typeof value === "symbol") return "symbol";
|
|
16086
16766
|
if (value === null) {
|
|
16087
16767
|
return "null";
|
|
@@ -16115,6 +16795,7 @@ async function toNumericPrimitive(value, context, hint = "number") {
|
|
|
16115
16795
|
throw new TypeError("Expected a sandbox value.");
|
|
16116
16796
|
}
|
|
16117
16797
|
function toNumber(value) {
|
|
16798
|
+
if (typeof value === "bigint") throw new TypeError("Cannot convert a BigInt value to a number");
|
|
16118
16799
|
if (typeof value === "symbol") throw new TypeError("Cannot convert a Symbol value to a number");
|
|
16119
16800
|
if (isSandboxDate(value)) return dateTime(value);
|
|
16120
16801
|
if (typeof value === "number") {
|
|
@@ -16656,7 +17337,7 @@ async function callRegexMethod(target, methodName, args, budget, context) {
|
|
|
16656
17337
|
cursor = target.lastIndex;
|
|
16657
17338
|
const lastIndex = await sandboxNumber(cursor, budget, context);
|
|
16658
17339
|
const match = executeRegex(target, input, lastIndex);
|
|
16659
|
-
return toMatchArray(match, input);
|
|
17340
|
+
return toMatchArray(match, input, budget);
|
|
16660
17341
|
} finally {
|
|
16661
17342
|
budget.setRetainedValues(retained, void 0);
|
|
16662
17343
|
}
|
|
@@ -16707,17 +17388,26 @@ async function regexToString(target, budget, context) {
|
|
|
16707
17388
|
function executeRegex(target, input, lastIndex) {
|
|
16708
17389
|
const pattern = getSandboxRegexPattern(target);
|
|
16709
17390
|
const match = matchRegex(pattern, input, lastIndex);
|
|
16710
|
-
if (pattern.flags.global) {
|
|
17391
|
+
if (pattern.flags.global || pattern.flags.sticky) {
|
|
16711
17392
|
target.lastIndex = match === null ? 0 : match.index + match.text.length;
|
|
16712
17393
|
}
|
|
16713
17394
|
return match;
|
|
16714
17395
|
}
|
|
16715
|
-
function toMatchArray(match, input) {
|
|
17396
|
+
function toMatchArray(match, input, budget) {
|
|
16716
17397
|
if (match === null) {
|
|
16717
17398
|
return null;
|
|
16718
17399
|
}
|
|
17400
|
+
budget?.allocateArrayLength(match.captures.length + 1);
|
|
16719
17401
|
const result = [match.text, ...match.captures];
|
|
16720
|
-
|
|
17402
|
+
if (match.groups !== void 0) setSandboxPrototype(match.groups, null, budget);
|
|
17403
|
+
if (match.indicesGroups !== void 0) setSandboxPrototype(match.indicesGroups, null, budget);
|
|
17404
|
+
Object.assign(result, { index: match.index, input, groups: match.groups });
|
|
17405
|
+
if (match.indices !== void 0) {
|
|
17406
|
+
budget?.allocateArrayLength(match.indices.length);
|
|
17407
|
+
budget?.allocateArrayLength(2);
|
|
17408
|
+
Object.assign(match.indices, { groups: match.indicesGroups });
|
|
17409
|
+
Object.assign(result, { indices: match.indices });
|
|
17410
|
+
}
|
|
16721
17411
|
return result;
|
|
16722
17412
|
}
|
|
16723
17413
|
|
|
@@ -16727,9 +17417,10 @@ function nextRegExpIterator(iterator, budget) {
|
|
|
16727
17417
|
budget?.visitNode();
|
|
16728
17418
|
if (state.exhausted) return { value: void 0, done: true };
|
|
16729
17419
|
const matcher = state.matcher;
|
|
17420
|
+
if (!isSandboxRegex(matcher)) throw new TypeError("Custom RegExp iterator execution requires a sandbox context.");
|
|
16730
17421
|
const input = state.input;
|
|
16731
17422
|
const match = executeRegex(matcher, input, Number(matcher.lastIndex));
|
|
16732
|
-
if (match === null || !matcher.flags.includes("g")) {
|
|
17423
|
+
if (match === null || !(state.global ?? matcher.flags.includes("g"))) {
|
|
16733
17424
|
state.exhausted = true;
|
|
16734
17425
|
state.matcher = void 0;
|
|
16735
17426
|
state.input = void 0;
|
|
@@ -16737,12 +17428,52 @@ function nextRegExpIterator(iterator, budget) {
|
|
|
16737
17428
|
if (match === null) return { value: void 0, done: true };
|
|
16738
17429
|
if (!state.exhausted && match.text.length === 0) {
|
|
16739
17430
|
const index = Number(matcher.lastIndex);
|
|
16740
|
-
const unicode = matcher.flags.includes("u") || matcher.flags.includes("v");
|
|
17431
|
+
const unicode = state.unicode ?? (matcher.flags.includes("u") || matcher.flags.includes("v"));
|
|
16741
17432
|
const codePoint = input.codePointAt(index);
|
|
16742
17433
|
matcher.lastIndex = index + (unicode && codePoint !== void 0 && codePoint > 65535 ? 2 : 1);
|
|
16743
17434
|
}
|
|
16744
|
-
|
|
16745
|
-
|
|
17435
|
+
return { value: toMatchArray(match, input, budget), done: false };
|
|
17436
|
+
}
|
|
17437
|
+
async function nextObservableRegExpIterator(iterator, budget, context) {
|
|
17438
|
+
const state = regexpIteratorState(iterator);
|
|
17439
|
+
if (state.exhausted) return { value: void 0, done: true };
|
|
17440
|
+
const matcher = state.matcher;
|
|
17441
|
+
if (isSandboxRegex(matcher) && !hasRegexPropertyOverride(matcher, ["exec"], budget) && (matcher.lastIndex === null || typeof matcher.lastIndex !== "object"))
|
|
17442
|
+
return nextRegExpIterator(iterator, budget);
|
|
17443
|
+
const input = state.input;
|
|
17444
|
+
let result;
|
|
17445
|
+
let field;
|
|
17446
|
+
const release = retainValues(budget, () => [iterator, matcher, input, result, field]);
|
|
17447
|
+
const read = (value, key) => {
|
|
17448
|
+
if (context.getProperty !== void 0) return context.getProperty(value, key);
|
|
17449
|
+
const descriptor = getSandboxPropertyDescriptor(value, key, budget);
|
|
17450
|
+
return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
|
|
17451
|
+
};
|
|
17452
|
+
try {
|
|
17453
|
+
budget.visitNode();
|
|
17454
|
+
result = await regexExec(matcher, input, budget, context);
|
|
17455
|
+
const global = state.global ?? (isSandboxRegex(matcher) && matcher.flags.includes("g"));
|
|
17456
|
+
if (result === null || !global) {
|
|
17457
|
+
state.exhausted = true;
|
|
17458
|
+
state.matcher = void 0;
|
|
17459
|
+
state.input = void 0;
|
|
17460
|
+
return result === null ? { value: void 0, done: true } : { value: result, done: false };
|
|
17461
|
+
}
|
|
17462
|
+
field = await read(result, "0");
|
|
17463
|
+
const text = await sandboxString(field, budget, context);
|
|
17464
|
+
field = void 0;
|
|
17465
|
+
if (text.length === 0) {
|
|
17466
|
+
field = await read(matcher, "lastIndex");
|
|
17467
|
+
const index = normalizeLastIndex(await sandboxNumber(field, budget, context));
|
|
17468
|
+
field = void 0;
|
|
17469
|
+
const unicode = state.unicode ?? (isSandboxRegex(matcher) && (matcher.flags.includes("u") || matcher.flags.includes("v")));
|
|
17470
|
+
const point = input.codePointAt(index);
|
|
17471
|
+
await setSandboxProperty(matcher, "lastIndex", index + (unicode && point !== void 0 && point > 65535 ? 2 : 1), budget, true, context);
|
|
17472
|
+
}
|
|
17473
|
+
return { value: result, done: false };
|
|
17474
|
+
} finally {
|
|
17475
|
+
release();
|
|
17476
|
+
}
|
|
16746
17477
|
}
|
|
16747
17478
|
function getRegExpIteratorMember(property, budget) {
|
|
16748
17479
|
if (property === Symbol.toStringTag) return "RegExp String Iterator";
|
|
@@ -16759,7 +17490,7 @@ function getRegExpIteratorMember(property, budget) {
|
|
|
16759
17490
|
const receiver = context?.thisValue;
|
|
16760
17491
|
if (!isSandboxRegExpIterator(receiver))
|
|
16761
17492
|
throw new TypeError("RegExp string iterator next requires a matching receiver.");
|
|
16762
|
-
return nextRegExpIterator(receiver, budget);
|
|
17493
|
+
return context === void 0 ? nextRegExpIterator(receiver, budget) : nextObservableRegExpIterator(receiver, budget, context);
|
|
16763
17494
|
}
|
|
16764
17495
|
});
|
|
16765
17496
|
}
|
|
@@ -16947,8 +17678,11 @@ function getSandboxIterator(value, budget, context) {
|
|
|
16947
17678
|
}
|
|
16948
17679
|
if (isSandboxCollectionIterator(value))
|
|
16949
17680
|
return { next: () => nextCollectionIterator(value, budget), snapshotIndex: () => 0 };
|
|
16950
|
-
if (isSandboxRegExpIterator(value))
|
|
17681
|
+
if (isSandboxRegExpIterator(value)) {
|
|
17682
|
+
if (context !== void 0 && budget !== void 0)
|
|
17683
|
+
return { asynchronous: true, next: () => nextObservableRegExpIterator(value, budget, context), snapshotIndex: () => 0 };
|
|
16951
17684
|
return { next: () => nextRegExpIterator(value, budget), snapshotIndex: () => 0 };
|
|
17685
|
+
}
|
|
16952
17686
|
if (isGuestHostObject(value)) return getHostObjectIterator(value);
|
|
16953
17687
|
if (isFloat32Array(value)) {
|
|
16954
17688
|
return syncIterator(Float32Array.prototype.values.call(value));
|
|
@@ -17659,6 +18393,7 @@ function encodeReplayData(value, options = {}) {
|
|
|
17659
18393
|
if (depth > MAX_DATA_DEPTH) throw new TypeError("Replay data exceeds the nesting limit.");
|
|
17660
18394
|
if (entry === null || typeof entry === "boolean" || typeof entry === "string") return entry;
|
|
17661
18395
|
if (entry === void 0) return { tag: "undefined" };
|
|
18396
|
+
if (typeof entry === "bigint") return { tag: "bigint", value: String(entry) };
|
|
17662
18397
|
if (typeof entry === "symbol") {
|
|
17663
18398
|
let id2 = symbols.get(entry);
|
|
17664
18399
|
if (id2 === void 0) {
|
|
@@ -17755,7 +18490,16 @@ function encodeReplayData(value, options = {}) {
|
|
|
17755
18490
|
}
|
|
17756
18491
|
let symbolIndex = 0;
|
|
17757
18492
|
const symbolEntries = serializeSymbolProperties(entry, (value2) => encode(value2, depth + 1, [...path, { symbol: Math.floor(symbolIndex++ / 2) }]));
|
|
17758
|
-
nodes[id] = {
|
|
18493
|
+
nodes[id] = {
|
|
18494
|
+
kind: "regexp-iterator",
|
|
18495
|
+
matcher: child(snapshot.matcher, "<matcher>"),
|
|
18496
|
+
input: child(snapshot.input, "<input>"),
|
|
18497
|
+
exhausted: snapshot.exhausted,
|
|
18498
|
+
properties,
|
|
18499
|
+
extensible: Object.isExtensible(entry),
|
|
18500
|
+
symbolEntries,
|
|
18501
|
+
...snapshot.global === void 0 ? {} : { global: snapshot.global, unicode: snapshot.unicode }
|
|
18502
|
+
};
|
|
17759
18503
|
} else if (isSandboxCollectionIterator(entry)) {
|
|
17760
18504
|
const snapshot = snapshotCollectionIterator(entry);
|
|
17761
18505
|
const properties = /* @__PURE__ */ Object.create(null);
|
|
@@ -17809,6 +18553,7 @@ function encodeReplayData(value, options = {}) {
|
|
|
17809
18553
|
nodes[id] = {
|
|
17810
18554
|
kind: Array.isArray(entry) ? "array" : "object",
|
|
17811
18555
|
nullPrototype: prototype === null,
|
|
18556
|
+
...hasNullObjectPrototype(entry) ? { sandboxNullPrototype: true } : {},
|
|
17812
18557
|
...errorType === void 0 ? {} : { errorType },
|
|
17813
18558
|
extensible: Object.isExtensible(entry),
|
|
17814
18559
|
properties,
|
|
@@ -17851,6 +18596,11 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
17851
18596
|
return capability;
|
|
17852
18597
|
}
|
|
17853
18598
|
if (own(atom, "tag") === "undefined") return void 0;
|
|
18599
|
+
if (own(atom, "tag") === "bigint") {
|
|
18600
|
+
const value = own(atom, "value");
|
|
18601
|
+
validateBigIntData(value);
|
|
18602
|
+
return BigInt(value);
|
|
18603
|
+
}
|
|
17854
18604
|
if (atom.tag === "number") {
|
|
17855
18605
|
switch (own(atom, "value")) {
|
|
17856
18606
|
case "NaN":
|
|
@@ -17920,7 +18670,7 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
17920
18670
|
const payload = own(node, "value");
|
|
17921
18671
|
const payloadRecord = payload !== null && typeof payload === "object" ? record(payload) : void 0;
|
|
17922
18672
|
const symbolReference = payloadRecord !== void 0 && own(payloadRecord, "tag") === "ref" && Number.isSafeInteger(payloadRecord.id) && Number(payloadRecord.id) >= 0 && Number(payloadRecord.id) < nodes.length && own(record(nodes[Number(payloadRecord.id)]), "kind") === "symbol";
|
|
17923
|
-
if (typeof payload !== "number" && typeof payload !== "string" && typeof payload !== "boolean" && !symbolReference && (payload === null || typeof payload !== "object" || own(record(payload), "tag")
|
|
18673
|
+
if (typeof payload !== "number" && typeof payload !== "string" && typeof payload !== "boolean" && !symbolReference && (payload === null || typeof payload !== "object" || !["number", "bigint"].includes(String(own(record(payload), "tag")))))
|
|
17924
18674
|
throw new TypeError("Invalid boxed primitive payload.");
|
|
17925
18675
|
const result3 = createSandboxBox(child(payload));
|
|
17926
18676
|
restored.set(id, result3);
|
|
@@ -17953,9 +18703,15 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
17953
18703
|
restored.set(id, result3);
|
|
17954
18704
|
const matcher = child(own(node, "matcher"));
|
|
17955
18705
|
const input2 = child(own(node, "input"));
|
|
17956
|
-
if (
|
|
18706
|
+
if ((node.global !== void 0 || node.unicode !== void 0) && (typeof node.global !== "boolean" || typeof node.unicode !== "boolean")) throw new TypeError("Invalid replay RegExp iterator modes.");
|
|
18707
|
+
if (matcher !== void 0 && (node.global === void 0 ? !isSandboxRegex(matcher) : matcher === null || typeof matcher !== "object")) throw new TypeError("Invalid replay RegExp iterator matcher.");
|
|
17957
18708
|
if (input2 !== void 0 && typeof input2 !== "string") throw new TypeError("Invalid replay RegExp iterator input.");
|
|
17958
|
-
restoreSandboxRegExpIterator({
|
|
18709
|
+
restoreSandboxRegExpIterator({
|
|
18710
|
+
matcher,
|
|
18711
|
+
input: input2,
|
|
18712
|
+
exhausted,
|
|
18713
|
+
...node.global === void 0 ? {} : { global: node.global, unicode: node.unicode }
|
|
18714
|
+
}, result3);
|
|
17959
18715
|
defineProperties(result3, record(own(node, "properties")), child, node.symbolEntries);
|
|
17960
18716
|
if (!node.extensible) Object.preventExtensions(result3);
|
|
17961
18717
|
return result3;
|
|
@@ -18025,6 +18781,10 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
18025
18781
|
throw new TypeError("Invalid replay object metadata.");
|
|
18026
18782
|
}
|
|
18027
18783
|
const result2 = kind === "array" ? [] : Object.create(node.nullPrototype ? null : Object.prototype);
|
|
18784
|
+
if (Object.hasOwn(node, "sandboxNullPrototype")) {
|
|
18785
|
+
if (kind !== "object" || node.sandboxNullPrototype !== true) throw new TypeError("Invalid replay object prototype.");
|
|
18786
|
+
setSandboxPrototype(result2, null);
|
|
18787
|
+
}
|
|
18028
18788
|
if (Object.hasOwn(node, "errorType")) {
|
|
18029
18789
|
sandboxErrorTypes.set(result2, node.errorType);
|
|
18030
18790
|
}
|
|
@@ -18661,7 +19421,7 @@ function wrapSandboxClosureForHost(closure, stackFrames, budget, compileOwner, c
|
|
|
18661
19421
|
return wrapped;
|
|
18662
19422
|
}
|
|
18663
19423
|
function isSandboxLikeValue(value) {
|
|
18664
|
-
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
19424
|
+
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
|
|
18665
19425
|
return true;
|
|
18666
19426
|
}
|
|
18667
19427
|
if (isSandboxClosure(value) || isSandboxPromise(value)) {
|
|
@@ -18726,7 +19486,7 @@ function copyHostValueToSandbox(value, stackFrames, options, state, path) {
|
|
|
18726
19486
|
if (options.realm === void 0 || options.errorData || options.hostCalls !== void 0) throw new TypeError("Live capabilities are not portable replay or error data.");
|
|
18727
19487
|
return importHostCapability(value, options.realm.owner);
|
|
18728
19488
|
}
|
|
18729
|
-
if (value === null || value === void 0 || typeof value === "number" || typeof value === "boolean") {
|
|
19489
|
+
if (value === null || value === void 0 || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
|
|
18730
19490
|
return value;
|
|
18731
19491
|
}
|
|
18732
19492
|
if (typeof value === "string") {
|
|
@@ -19205,12 +19965,16 @@ function getDatePrototype(value, budget, owner) {
|
|
|
19205
19965
|
var defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
|
|
19206
19966
|
var defaultValueHook = /* @__PURE__ */ Symbol("defaultValueHook");
|
|
19207
19967
|
var joiningArrays = /* @__PURE__ */ new WeakSet();
|
|
19208
|
-
function sandboxNumber(value, budget, context) {
|
|
19968
|
+
function sandboxNumber(value, budget, context, allowBigInt = false) {
|
|
19969
|
+
const convert = (primitive) => {
|
|
19970
|
+
if (typeof primitive === "bigint" && !allowBigInt) throw new TypeError("Cannot convert a BigInt value to a number");
|
|
19971
|
+
return Number(primitive);
|
|
19972
|
+
};
|
|
19209
19973
|
if (value === null || typeof value !== "object") {
|
|
19210
19974
|
if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
|
|
19211
|
-
return
|
|
19975
|
+
return convert(value);
|
|
19212
19976
|
}
|
|
19213
|
-
return objectToPrimitive(value, budget, context, /* @__PURE__ */ new Set(), "number").then(
|
|
19977
|
+
return objectToPrimitive(value, budget, context, /* @__PURE__ */ new Set(), "number").then(convert);
|
|
19214
19978
|
}
|
|
19215
19979
|
function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
|
|
19216
19980
|
if (typeof value === "symbol") throw new TypeError("Cannot convert a Symbol value to a string");
|
|
@@ -21214,6 +21978,10 @@ function measureSandboxData(values, options = {}) {
|
|
|
21214
21978
|
const seenSymbols = /* @__PURE__ */ new Set();
|
|
21215
21979
|
let usage = 0;
|
|
21216
21980
|
const visit = (value, depth = 0) => {
|
|
21981
|
+
if (typeof value === "bigint") {
|
|
21982
|
+
usage += value.toString(16).length;
|
|
21983
|
+
return;
|
|
21984
|
+
}
|
|
21217
21985
|
if (typeof value === "symbol") {
|
|
21218
21986
|
if (!seenSymbols.has(value)) {
|
|
21219
21987
|
seenSymbols.add(value);
|
|
@@ -21472,7 +22240,7 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
21472
22240
|
const copy = restoreSandboxRegExpIterator({ matcher: void 0, input: void 0, exhausted: true });
|
|
21473
22241
|
state.seen.set(value, copy);
|
|
21474
22242
|
const matcher = copyToSandbox(snapshot.matcher, state, `${path}.<matcher>`, true, depth + 1);
|
|
21475
|
-
if (matcher !== void 0 && !isSandboxRegex(matcher)) throw new TypeError("Invalid RegExp iterator matcher.");
|
|
22243
|
+
if (matcher !== void 0 && (snapshot.global === void 0 ? !isSandboxRegex(matcher) : matcher === null || typeof matcher !== "object")) throw new TypeError("Invalid RegExp iterator matcher.");
|
|
21476
22244
|
restoreSandboxRegExpIterator({ ...snapshot, matcher }, copy);
|
|
21477
22245
|
for (const entry of getEnumerableObjectEntries(value, path)) {
|
|
21478
22246
|
defineOwnDataProperty(copy, entry.key, copyToSandbox(entry.value, state, joinPath2(path, entry.key), true, depth + 1));
|
|
@@ -21660,6 +22428,7 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
21660
22428
|
const copy = createPlainObject(
|
|
21661
22429
|
!cloneSandboxCollections || Object.getPrototypeOf(value) === null
|
|
21662
22430
|
);
|
|
22431
|
+
if (!state.structuredClone && hasNullObjectPrototype(value)) setSandboxPrototype(copy, null);
|
|
21663
22432
|
state.seen.set(value, copy);
|
|
21664
22433
|
const errorType = sandboxErrorTypes.get(value);
|
|
21665
22434
|
if (errorType !== void 0) sandboxErrorTypes.set(copy, errorType);
|
|
@@ -21871,7 +22640,7 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
21871
22640
|
if (existing !== void 0) {
|
|
21872
22641
|
return existing;
|
|
21873
22642
|
}
|
|
21874
|
-
const copy = createPlainObject(Object.getPrototypeOf(value) === null);
|
|
22643
|
+
const copy = createPlainObject(hasNullObjectPrototype(value) || Object.getPrototypeOf(value) === null);
|
|
21875
22644
|
state.seen.set(value, copy);
|
|
21876
22645
|
for (const entry of getEnumerableObjectEntries(value, path)) {
|
|
21877
22646
|
defineOwnDataProperty(
|
|
@@ -21885,7 +22654,7 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
21885
22654
|
throw new TypeError(`Unsupported sandbox value at ${path}: ${describeValue2(value)}`);
|
|
21886
22655
|
}
|
|
21887
22656
|
function isSandboxPrimitive(value) {
|
|
21888
|
-
return value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol";
|
|
22657
|
+
return value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean" || typeof value === "symbol";
|
|
21889
22658
|
}
|
|
21890
22659
|
function isHostPromise(value) {
|
|
21891
22660
|
return value instanceof Promise;
|
|
@@ -23609,6 +24378,7 @@ var KNOWN_RUNTIME_GLOBALS = [
|
|
|
23609
24378
|
"AggregateError",
|
|
23610
24379
|
"Array",
|
|
23611
24380
|
"Boolean",
|
|
24381
|
+
"BigInt",
|
|
23612
24382
|
"Date",
|
|
23613
24383
|
"Error",
|
|
23614
24384
|
"Infinity",
|
|
@@ -26880,6 +27650,7 @@ var ASAsyncNotNeededScanner = class {
|
|
|
26880
27650
|
case "MetaProperty":
|
|
26881
27651
|
case "NullLiteral":
|
|
26882
27652
|
case "NumericLiteral":
|
|
27653
|
+
case "BigIntLiteral":
|
|
26883
27654
|
case "RegexLiteral":
|
|
26884
27655
|
case "StringLiteral":
|
|
26885
27656
|
case "UndefinedLiteral":
|
|
@@ -27161,6 +27932,7 @@ function expressionContainsAwait(node) {
|
|
|
27161
27932
|
case "MetaProperty":
|
|
27162
27933
|
case "NullLiteral":
|
|
27163
27934
|
case "NumericLiteral":
|
|
27935
|
+
case "BigIntLiteral":
|
|
27164
27936
|
case "RegexLiteral":
|
|
27165
27937
|
case "StringLiteral":
|
|
27166
27938
|
case "ThisExpression":
|
|
@@ -30574,6 +31346,7 @@ var ASMissingAsyncScanner = class {
|
|
|
30574
31346
|
case "MetaProperty":
|
|
30575
31347
|
case "NullLiteral":
|
|
30576
31348
|
case "NumericLiteral":
|
|
31349
|
+
case "BigIntLiteral":
|
|
30577
31350
|
case "RegexLiteral":
|
|
30578
31351
|
case "StringLiteral":
|
|
30579
31352
|
case "UndefinedLiteral":
|
|
@@ -30844,6 +31617,7 @@ function expressionContainsAwait2(node) {
|
|
|
30844
31617
|
case "MetaProperty":
|
|
30845
31618
|
case "NullLiteral":
|
|
30846
31619
|
case "NumericLiteral":
|
|
31620
|
+
case "BigIntLiteral":
|
|
30847
31621
|
case "RegexLiteral":
|
|
30848
31622
|
case "StringLiteral":
|
|
30849
31623
|
case "ThisExpression":
|
|
@@ -34162,29 +34936,53 @@ function createConsoleJsonGlobals(options) {
|
|
|
34162
34936
|
};
|
|
34163
34937
|
}
|
|
34164
34938
|
async function stringifyJson(value, replacer, indent, budget, context) {
|
|
34165
|
-
|
|
34166
|
-
|
|
34167
|
-
|
|
34168
|
-
|
|
34169
|
-
|
|
34170
|
-
|
|
34171
|
-
|
|
34172
|
-
|
|
34173
|
-
|
|
34174
|
-
|
|
34175
|
-
|
|
34176
|
-
|
|
34177
|
-
|
|
34178
|
-
|
|
34179
|
-
|
|
34180
|
-
|
|
34181
|
-
|
|
34182
|
-
|
|
34183
|
-
|
|
34184
|
-
|
|
34185
|
-
|
|
34939
|
+
const allocation = {};
|
|
34940
|
+
let propertyList;
|
|
34941
|
+
const release = retainValues(budget, () => [value, replacer, indent]);
|
|
34942
|
+
try {
|
|
34943
|
+
if (Array.isArray(replacer)) {
|
|
34944
|
+
propertyList = [];
|
|
34945
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34946
|
+
let size = 0;
|
|
34947
|
+
const state = { budget, context, gap: "", stack: [] };
|
|
34948
|
+
const length = replacer.length;
|
|
34949
|
+
for (let index = 0; index < length; index++) {
|
|
34950
|
+
budget.visitNode();
|
|
34951
|
+
const entry = await getStringifyProperty(replacer, String(index), state);
|
|
34952
|
+
const primitive = isSandboxBox(entry) ? boxedValue(entry) : entry;
|
|
34953
|
+
if (typeof primitive !== "string" && typeof primitive !== "number") continue;
|
|
34954
|
+
const key = await sandboxString(entry, budget, context);
|
|
34955
|
+
if (seen.has(key)) continue;
|
|
34956
|
+
budget.allocateArrayLength(propertyList.length + 1);
|
|
34957
|
+
size += key.length + 2;
|
|
34958
|
+
budget.setRetainedDataUsage(allocation, size);
|
|
34959
|
+
propertyList.push(key);
|
|
34960
|
+
seen.add(key);
|
|
34961
|
+
}
|
|
34962
|
+
}
|
|
34963
|
+
if (isSandboxBox(indent)) {
|
|
34964
|
+
const primitive = boxedValue(indent);
|
|
34965
|
+
if (typeof primitive === "number") indent = await sandboxNumber(indent, budget, context);
|
|
34966
|
+
else if (typeof primitive === "string") indent = await sandboxString(indent, budget, context);
|
|
34967
|
+
}
|
|
34968
|
+
const holder = {};
|
|
34969
|
+
defineDataProperty2(holder, "", value);
|
|
34970
|
+
const output = await stringifyProperty("", holder, {
|
|
34971
|
+
budget,
|
|
34972
|
+
context,
|
|
34973
|
+
gap: normalizeStringifyGap(indent),
|
|
34974
|
+
replacer: isSandboxClosure(replacer) ? replacer : void 0,
|
|
34975
|
+
propertyList,
|
|
34976
|
+
stack: []
|
|
34977
|
+
});
|
|
34978
|
+
if (output === void 0) {
|
|
34979
|
+
return void 0;
|
|
34980
|
+
}
|
|
34981
|
+
return budget.allocateString(output);
|
|
34982
|
+
} finally {
|
|
34983
|
+
budget.setRetainedDataUsage(allocation, 0);
|
|
34984
|
+
release();
|
|
34186
34985
|
}
|
|
34187
|
-
return budget.allocateString(output);
|
|
34188
34986
|
}
|
|
34189
34987
|
async function stringifyProperty(key, holder, state, indent = "") {
|
|
34190
34988
|
let value = await getStringifyProperty(holder, key, state);
|
|
@@ -34192,7 +34990,7 @@ async function stringifyProperty(key, holder, state, indent = "") {
|
|
|
34192
34990
|
try {
|
|
34193
34991
|
if (isSandboxDate(value) && getSandboxPropertyDescriptor(value, "toJSON", state.budget) === void 0) {
|
|
34194
34992
|
value = await dateToJSON(value, state.budget, state.context);
|
|
34195
|
-
} else if (isStringifyContainer(value)) {
|
|
34993
|
+
} else if (typeof value === "bigint" || isSandboxClosure(value) || isStringifyContainer(value)) {
|
|
34196
34994
|
const toJSON = await getStringifyProperty(value, "toJSON", state);
|
|
34197
34995
|
if (isSandboxClosure(toJSON)) {
|
|
34198
34996
|
value = await callStringifyClosure(toJSON, [key], value, state);
|
|
@@ -34274,7 +35072,7 @@ async function stringifyObject(value, state, indent) {
|
|
|
34274
35072
|
const release = retainValues(state.budget, () => entries);
|
|
34275
35073
|
try {
|
|
34276
35074
|
const nextIndent = indent + state.gap;
|
|
34277
|
-
for (const key of Object.keys(value)) {
|
|
35075
|
+
for (const key of state.propertyList ?? Object.keys(value)) {
|
|
34278
35076
|
const serialized = await stringifyProperty(key, value, state, nextIndent);
|
|
34279
35077
|
if (serialized !== void 0) {
|
|
34280
35078
|
entries.push(`${quoteJsonString(key)}:${state.gap === "" ? "" : " "}${serialized}`);
|
|
@@ -34337,19 +35135,17 @@ function isStringifyObject(value) {
|
|
|
34337
35135
|
return isStringifyContainer(value) && !Array.isArray(value);
|
|
34338
35136
|
}
|
|
34339
35137
|
function toSandboxValue(value) {
|
|
34340
|
-
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || isSandboxClosure(value) || isSandboxPromise(value) || Array.isArray(value) || isStringifyContainer(value)) {
|
|
35138
|
+
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "symbol" || typeof value === "boolean" || isSandboxClosure(value) || isSandboxPromise(value) || Array.isArray(value) || isStringifyContainer(value)) {
|
|
34341
35139
|
return value;
|
|
34342
35140
|
}
|
|
34343
|
-
if (typeof value === "bigint") {
|
|
34344
|
-
throw new TypeError("Do not know how to serialize a BigInt.");
|
|
34345
|
-
}
|
|
34346
35141
|
throw new TypeError(
|
|
34347
35142
|
`JSON.stringify(value) produced an unsupported value of type ${typeof value}.`
|
|
34348
35143
|
);
|
|
34349
35144
|
}
|
|
34350
35145
|
function getStringifyProperty(target, key, state) {
|
|
34351
35146
|
if (state.context?.getProperty !== void 0) return state.context.getProperty(target, key);
|
|
34352
|
-
const
|
|
35147
|
+
const object = typeof target === "bigint" ? getBoxedPrototype(target, state.budget) : target;
|
|
35148
|
+
const descriptor = object === void 0 ? void 0 : getSandboxPropertyDescriptor(object, key, state.budget);
|
|
34353
35149
|
return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, target, state.context);
|
|
34354
35150
|
}
|
|
34355
35151
|
function copyJsonToSandbox(value, budget) {
|
|
@@ -34388,6 +35184,90 @@ function defineDataProperty2(target, key, value) {
|
|
|
34388
35184
|
});
|
|
34389
35185
|
}
|
|
34390
35186
|
|
|
35187
|
+
// packages/safe-js/src/interp/methods/regex-split.ts
|
|
35188
|
+
async function regexSplit(target, input, limit, constructor, budget, context) {
|
|
35189
|
+
if (target === null || typeof target !== "object") throw new TypeError("RegExp split requires an object receiver.");
|
|
35190
|
+
let string;
|
|
35191
|
+
let species;
|
|
35192
|
+
let field;
|
|
35193
|
+
let flags;
|
|
35194
|
+
let matcher;
|
|
35195
|
+
let match;
|
|
35196
|
+
const result = [];
|
|
35197
|
+
const release = retainValues(budget, () => [target, input, limit, string, species, field, flags, matcher, match, result]);
|
|
35198
|
+
const read = (value, key) => {
|
|
35199
|
+
if (context?.getProperty !== void 0) return context.getProperty(value, key);
|
|
35200
|
+
const descriptor = getSandboxPropertyDescriptor(value, key, budget);
|
|
35201
|
+
return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
|
|
35202
|
+
};
|
|
35203
|
+
const append = (value) => {
|
|
35204
|
+
budget.allocateArrayLength(result.length + 1);
|
|
35205
|
+
result.push(value);
|
|
35206
|
+
};
|
|
35207
|
+
try {
|
|
35208
|
+
string = await sandboxString(input, budget, context);
|
|
35209
|
+
input = void 0;
|
|
35210
|
+
field = await read(target, "constructor");
|
|
35211
|
+
species = constructor;
|
|
35212
|
+
if (field !== void 0) {
|
|
35213
|
+
if (field === null || typeof field !== "object") throw new TypeError("Invalid RegExp species constructor.");
|
|
35214
|
+
species = await read(field, Symbol.species);
|
|
35215
|
+
if (species === null || species === void 0) species = constructor;
|
|
35216
|
+
}
|
|
35217
|
+
field = void 0;
|
|
35218
|
+
if (!isSandboxClosure(species) || species.construct === void 0) throw new TypeError("RegExp species must be a constructor.");
|
|
35219
|
+
field = await read(target, "flags");
|
|
35220
|
+
flags = await sandboxString(field, budget, context);
|
|
35221
|
+
field = void 0;
|
|
35222
|
+
const unicode = flags.includes("u") || flags.includes("v");
|
|
35223
|
+
if (!flags.includes("y")) flags = budget.allocateString(flags + "y");
|
|
35224
|
+
matcher = await invokeBuiltinClosure(species, [target, flags], budget, context, void 0, true);
|
|
35225
|
+
const maximum = limit === void 0 ? 2 ** 32 - 1 : await sandboxNumber(limit, budget, context) >>> 0;
|
|
35226
|
+
limit = void 0;
|
|
35227
|
+
if (maximum === 0) return result;
|
|
35228
|
+
if (string.length === 0) {
|
|
35229
|
+
match = await regexExec(matcher, string, budget, context);
|
|
35230
|
+
if (match === null) append(string);
|
|
35231
|
+
return result;
|
|
35232
|
+
}
|
|
35233
|
+
let end = 0;
|
|
35234
|
+
let index = 0;
|
|
35235
|
+
while (index < string.length) {
|
|
35236
|
+
budget.visitNode();
|
|
35237
|
+
match = void 0;
|
|
35238
|
+
await setSandboxProperty(matcher, "lastIndex", index, budget, true, context);
|
|
35239
|
+
match = await regexExec(matcher, string, budget, context);
|
|
35240
|
+
if (match !== null) {
|
|
35241
|
+
field = await read(matcher, "lastIndex");
|
|
35242
|
+
const next = Math.min(normalizeLastIndex(await sandboxNumber(field, budget, context)), string.length);
|
|
35243
|
+
field = void 0;
|
|
35244
|
+
if (next !== end) {
|
|
35245
|
+
append(budget.allocateString(string.slice(end, index)));
|
|
35246
|
+
if (result.length === maximum) return result;
|
|
35247
|
+
end = next;
|
|
35248
|
+
field = await read(match, "length");
|
|
35249
|
+
const length = normalizeLastIndex(await sandboxNumber(field, budget, context));
|
|
35250
|
+
field = void 0;
|
|
35251
|
+
for (let capture = 1; capture < length; capture++) {
|
|
35252
|
+
budget.visitNode();
|
|
35253
|
+
field = await read(match, String(capture));
|
|
35254
|
+
append(field);
|
|
35255
|
+
field = void 0;
|
|
35256
|
+
if (result.length === maximum) return result;
|
|
35257
|
+
}
|
|
35258
|
+
index = end;
|
|
35259
|
+
continue;
|
|
35260
|
+
}
|
|
35261
|
+
}
|
|
35262
|
+
index += unicode && (string.codePointAt(index) ?? 0) > 65535 ? 2 : 1;
|
|
35263
|
+
}
|
|
35264
|
+
append(budget.allocateString(string.slice(end)));
|
|
35265
|
+
return result;
|
|
35266
|
+
} finally {
|
|
35267
|
+
release();
|
|
35268
|
+
}
|
|
35269
|
+
}
|
|
35270
|
+
|
|
34391
35271
|
// packages/safe-js/src/interp/globals/regex.ts
|
|
34392
35272
|
function createRegexGlobals(options) {
|
|
34393
35273
|
const invoke = (construct) => async (args, context) => {
|
|
@@ -34452,7 +35332,55 @@ function createRegexGlobals(options) {
|
|
|
34452
35332
|
}
|
|
34453
35333
|
};
|
|
34454
35334
|
const constructor = createSandboxClosure({ guest: true, sandbox: true, name: "RegExp", length: 2, call: invoke(false), construct: invoke(true) });
|
|
35335
|
+
Object.defineProperty(materializeFunctionProperties(constructor), "escape", {
|
|
35336
|
+
value: createSandboxClosure({
|
|
35337
|
+
guest: true,
|
|
35338
|
+
sandbox: true,
|
|
35339
|
+
name: "escape",
|
|
35340
|
+
length: 1,
|
|
35341
|
+
call: (args) => {
|
|
35342
|
+
const input = args[0];
|
|
35343
|
+
if (typeof input !== "string") throw new TypeError("RegExp.escape requires a string.");
|
|
35344
|
+
const allocation = {};
|
|
35345
|
+
let escaped = "";
|
|
35346
|
+
try {
|
|
35347
|
+
for (const character of input) {
|
|
35348
|
+
options.budget.visitNode();
|
|
35349
|
+
const point = character.codePointAt(0);
|
|
35350
|
+
let part = character;
|
|
35351
|
+
if (escaped.length === 0 && (point >= 48 && point <= 57 || point >= 65 && point <= 90 || point >= 97 && point <= 122)) {
|
|
35352
|
+
part = `\\x${point.toString(16)}`;
|
|
35353
|
+
} else if ("^$\\.*+?()[]{}|/".includes(character)) {
|
|
35354
|
+
part = "\\" + character;
|
|
35355
|
+
} else {
|
|
35356
|
+
const control = "\f\n\r \v".indexOf(character);
|
|
35357
|
+
if (control !== -1) part = "\\" + "fnrtv"[control];
|
|
35358
|
+
else if (",-=<>#&!%:;@~'`\"".includes(character) || character.trim() === "" || point >= 55296 && point <= 57343) {
|
|
35359
|
+
part = point <= 255 ? `\\x${point.toString(16).padStart(2, "0")}` : `\\u${point.toString(16).padStart(4, "0")}`;
|
|
35360
|
+
}
|
|
35361
|
+
}
|
|
35362
|
+
options.budget.setRetainedDataUsage(allocation, escaped.length + part.length);
|
|
35363
|
+
escaped = options.budget.allocateString(escaped + part);
|
|
35364
|
+
}
|
|
35365
|
+
return escaped;
|
|
35366
|
+
} finally {
|
|
35367
|
+
options.budget.setRetainedDataUsage(allocation, 0);
|
|
35368
|
+
}
|
|
35369
|
+
}
|
|
35370
|
+
}),
|
|
35371
|
+
writable: true,
|
|
35372
|
+
configurable: true
|
|
35373
|
+
});
|
|
34455
35374
|
const prototype = /* @__PURE__ */ Object.create(null);
|
|
35375
|
+
Object.defineProperty(materializeFunctionProperties(constructor), Symbol.species, {
|
|
35376
|
+
get: accessorAdapter(createSandboxClosure({
|
|
35377
|
+
sandbox: true,
|
|
35378
|
+
name: "get [Symbol.species]",
|
|
35379
|
+
length: 0,
|
|
35380
|
+
call: (_args, context) => context?.thisValue
|
|
35381
|
+
}), "get"),
|
|
35382
|
+
configurable: true
|
|
35383
|
+
});
|
|
34456
35384
|
Object.defineProperty(materializeFunctionProperties(constructor), "prototype", { value: prototype, writable: false });
|
|
34457
35385
|
Object.defineProperty(prototype, "constructor", { value: constructor, writable: true, configurable: true });
|
|
34458
35386
|
Object.defineProperty(prototype, Symbol.search, {
|
|
@@ -34495,6 +35423,73 @@ function createRegexGlobals(options) {
|
|
|
34495
35423
|
writable: true,
|
|
34496
35424
|
configurable: true
|
|
34497
35425
|
});
|
|
35426
|
+
Object.defineProperty(prototype, Symbol.matchAll, {
|
|
35427
|
+
value: createSandboxClosure({
|
|
35428
|
+
guest: true,
|
|
35429
|
+
sandbox: true,
|
|
35430
|
+
name: "[Symbol.matchAll]",
|
|
35431
|
+
length: 1,
|
|
35432
|
+
call: async (args, context) => {
|
|
35433
|
+
const target = context?.thisValue;
|
|
35434
|
+
if (target === null || typeof target !== "object") throw new TypeError("RegExp matchAll requires an object receiver.");
|
|
35435
|
+
let input = args[0];
|
|
35436
|
+
let string;
|
|
35437
|
+
let species;
|
|
35438
|
+
let field;
|
|
35439
|
+
let flags;
|
|
35440
|
+
let matcher;
|
|
35441
|
+
const release = retainValues(options.budget, () => [target, input, string, species, field, flags, matcher]);
|
|
35442
|
+
const read = (value, key) => {
|
|
35443
|
+
if (context?.getProperty !== void 0) return context.getProperty(value, key);
|
|
35444
|
+
const descriptor = getSandboxPropertyDescriptor(value, key, options.budget);
|
|
35445
|
+
return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
|
|
35446
|
+
};
|
|
35447
|
+
try {
|
|
35448
|
+
string = await sandboxString(input, options.budget, context);
|
|
35449
|
+
input = void 0;
|
|
35450
|
+
field = await read(target, "constructor");
|
|
35451
|
+
species = constructor;
|
|
35452
|
+
if (field !== void 0) {
|
|
35453
|
+
if (field === null || typeof field !== "object") throw new TypeError("Invalid RegExp species constructor.");
|
|
35454
|
+
species = await read(field, Symbol.species);
|
|
35455
|
+
if (species === null || species === void 0) species = constructor;
|
|
35456
|
+
}
|
|
35457
|
+
field = void 0;
|
|
35458
|
+
if (!isSandboxClosure(species) || species.construct === void 0) throw new TypeError("RegExp species must be a constructor.");
|
|
35459
|
+
field = await read(target, "flags");
|
|
35460
|
+
flags = await sandboxString(field, options.budget, context);
|
|
35461
|
+
field = void 0;
|
|
35462
|
+
matcher = await invokeBuiltinClosure(species, [target, flags], options.budget, context, void 0, true);
|
|
35463
|
+
field = await read(target, "lastIndex");
|
|
35464
|
+
const cursor = normalizeLastIndex(await sandboxNumber(field, options.budget, context));
|
|
35465
|
+
field = void 0;
|
|
35466
|
+
await setSandboxProperty(matcher, "lastIndex", cursor, options.budget, true, context);
|
|
35467
|
+
return restoreSandboxRegExpIterator({
|
|
35468
|
+
matcher,
|
|
35469
|
+
input: string,
|
|
35470
|
+
exhausted: false,
|
|
35471
|
+
global: flags.includes("g"),
|
|
35472
|
+
unicode: flags.includes("u") || flags.includes("v")
|
|
35473
|
+
});
|
|
35474
|
+
} finally {
|
|
35475
|
+
release();
|
|
35476
|
+
}
|
|
35477
|
+
}
|
|
35478
|
+
}),
|
|
35479
|
+
writable: true,
|
|
35480
|
+
configurable: true
|
|
35481
|
+
});
|
|
35482
|
+
Object.defineProperty(prototype, Symbol.split, {
|
|
35483
|
+
value: createSandboxClosure({
|
|
35484
|
+
guest: true,
|
|
35485
|
+
sandbox: true,
|
|
35486
|
+
name: "[Symbol.split]",
|
|
35487
|
+
length: 2,
|
|
35488
|
+
call: (args, context) => regexSplit(context?.thisValue, args[0], args[1], constructor, options.budget, context)
|
|
35489
|
+
}),
|
|
35490
|
+
writable: true,
|
|
35491
|
+
configurable: true
|
|
35492
|
+
});
|
|
34498
35493
|
for (const name of ["exec", "test", "toString"]) {
|
|
34499
35494
|
Object.defineProperty(prototype, name, {
|
|
34500
35495
|
value: createSandboxClosure({
|
|
@@ -34705,6 +35700,100 @@ function createSymbolGlobal(budget) {
|
|
|
34705
35700
|
return constructor;
|
|
34706
35701
|
}
|
|
34707
35702
|
|
|
35703
|
+
// packages/safe-js/src/interp/globals/bigint.ts
|
|
35704
|
+
function createBigIntGlobal(budget) {
|
|
35705
|
+
const convert = async (value, context, allowNumber = false) => {
|
|
35706
|
+
const primitive = value !== null && typeof value === "object" ? await objectToPrimitive(value, budget, context, /* @__PURE__ */ new Set(), "number") : value;
|
|
35707
|
+
if (typeof primitive === "bigint") return primitive;
|
|
35708
|
+
if (typeof primitive !== "string" && typeof primitive !== "boolean" && !(allowNumber && typeof primitive === "number"))
|
|
35709
|
+
throw new TypeError("Cannot convert value to BigInt.");
|
|
35710
|
+
const size = typeof primitive === "string" ? primitive.length : 256;
|
|
35711
|
+
budget.visitNode(size);
|
|
35712
|
+
const allocation = {};
|
|
35713
|
+
budget.setRetainedDataUsage(allocation, size);
|
|
35714
|
+
try {
|
|
35715
|
+
return BigInt(primitive);
|
|
35716
|
+
} finally {
|
|
35717
|
+
budget.setRetainedDataUsage(allocation, 0);
|
|
35718
|
+
}
|
|
35719
|
+
};
|
|
35720
|
+
const constructor = createSandboxClosure({
|
|
35721
|
+
guest: true,
|
|
35722
|
+
sandbox: true,
|
|
35723
|
+
name: "BigInt",
|
|
35724
|
+
length: 1,
|
|
35725
|
+
call: ([value], context) => convert(value, context, true)
|
|
35726
|
+
});
|
|
35727
|
+
const prototype = /* @__PURE__ */ Object.create(null);
|
|
35728
|
+
Object.defineProperties(prototype, {
|
|
35729
|
+
constructor: { value: constructor, writable: true, configurable: true },
|
|
35730
|
+
valueOf: {
|
|
35731
|
+
value: createSandboxClosure({
|
|
35732
|
+
sandbox: true,
|
|
35733
|
+
name: "valueOf",
|
|
35734
|
+
length: 0,
|
|
35735
|
+
call: (_args, context) => primitiveReceiver(context?.thisValue, "bigint")
|
|
35736
|
+
}),
|
|
35737
|
+
writable: true,
|
|
35738
|
+
configurable: true
|
|
35739
|
+
},
|
|
35740
|
+
toString: {
|
|
35741
|
+
value: createSandboxClosure({
|
|
35742
|
+
sandbox: true,
|
|
35743
|
+
name: "toString",
|
|
35744
|
+
length: 1,
|
|
35745
|
+
call: async ([radix], context) => {
|
|
35746
|
+
const value = primitiveReceiver(context?.thisValue, "bigint");
|
|
35747
|
+
const base = radix === void 0 ? 10 : await sandboxNumber(radix, budget, context);
|
|
35748
|
+
const allocation = {};
|
|
35749
|
+
const size = value.toString(16).length * 4;
|
|
35750
|
+
budget.visitNode(size);
|
|
35751
|
+
budget.setRetainedDataUsage(allocation, size);
|
|
35752
|
+
try {
|
|
35753
|
+
return budget.allocateString(value.toString(base));
|
|
35754
|
+
} finally {
|
|
35755
|
+
budget.setRetainedDataUsage(allocation, 0);
|
|
35756
|
+
}
|
|
35757
|
+
}
|
|
35758
|
+
}),
|
|
35759
|
+
writable: true,
|
|
35760
|
+
configurable: true
|
|
35761
|
+
},
|
|
35762
|
+
[Symbol.toStringTag]: { value: "BigInt", configurable: true }
|
|
35763
|
+
});
|
|
35764
|
+
const properties = materializeFunctionProperties(constructor);
|
|
35765
|
+
Object.defineProperty(properties, "prototype", { value: prototype });
|
|
35766
|
+
for (const name of ["asIntN", "asUintN"]) {
|
|
35767
|
+
Object.defineProperty(properties, name, {
|
|
35768
|
+
writable: true,
|
|
35769
|
+
configurable: true,
|
|
35770
|
+
value: createSandboxClosure({
|
|
35771
|
+
sandbox: true,
|
|
35772
|
+
name,
|
|
35773
|
+
length: 2,
|
|
35774
|
+
call: async ([bits, input], context) => {
|
|
35775
|
+
const number = await sandboxNumber(bits, budget, context);
|
|
35776
|
+
const width = Number.isNaN(number) ? 0 : Math.trunc(number);
|
|
35777
|
+
if (width < 0 || !Number.isSafeInteger(width)) throw new RangeError("Invalid BigInt width.");
|
|
35778
|
+
const value = await convert(input, context);
|
|
35779
|
+
const size = value.toString(16).length;
|
|
35780
|
+
budget.visitNode(size);
|
|
35781
|
+
if (width >= size * 4 + 1 && (name === "asIntN" || value >= 0n)) return value;
|
|
35782
|
+
const allocation = {};
|
|
35783
|
+
budget.setRetainedDataUsage(allocation, Math.ceil(width / 4) + 1);
|
|
35784
|
+
try {
|
|
35785
|
+
return BigInt[name](width, value);
|
|
35786
|
+
} finally {
|
|
35787
|
+
budget.setRetainedDataUsage(allocation, 0);
|
|
35788
|
+
}
|
|
35789
|
+
}
|
|
35790
|
+
})
|
|
35791
|
+
});
|
|
35792
|
+
}
|
|
35793
|
+
installBoxedPrototype(budget, prototype, constructor, "bigint");
|
|
35794
|
+
return constructor;
|
|
35795
|
+
}
|
|
35796
|
+
|
|
34708
35797
|
// packages/safe-js/src/interp/globals.ts
|
|
34709
35798
|
function createBuiltinBindings(options) {
|
|
34710
35799
|
return {
|
|
@@ -34713,6 +35802,7 @@ function createBuiltinBindings(options) {
|
|
|
34713
35802
|
Float32Array: createFloat32ArrayGlobal(options.budget),
|
|
34714
35803
|
Date: createDateGlobal(options),
|
|
34715
35804
|
Symbol: createSymbolGlobal(options.budget),
|
|
35805
|
+
BigInt: createBigIntGlobal(options.budget),
|
|
34716
35806
|
...createErrorGlobals(options),
|
|
34717
35807
|
...createMathGlobals({ random: options.random }),
|
|
34718
35808
|
...createObjectArrayGlobals(options),
|
|
@@ -36839,4 +37929,4 @@ export {
|
|
|
36839
37929
|
FileSnapshotBackend,
|
|
36840
37930
|
run
|
|
36841
37931
|
};
|
|
36842
|
-
//# sourceMappingURL=chunk-
|
|
37932
|
+
//# sourceMappingURL=chunk-UZYQWFMY.js.map
|