@poe-platform/safe-js 0.1.197 → 0.1.199
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/safe-js/chunks/{chunk-7KLRGTR4.js → chunk-X5VIB5JV.js} +248 -49
- package/dist/safe-js/chunks/chunk-X5VIB5JV.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-GMRA5QVS.js → chunk-YWBUORD7.js} +2 -2
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.js +1 -1
- package/dist/safe-js/index.js +2 -2
- package/dist/safe-js/interp/regex/parse.d.ts +10 -0
- package/package.json +2 -2
- package/dist/safe-js/chunks/chunk-7KLRGTR4.js.map +0 -7
- /package/dist/safe-js/chunks/{chunk-GMRA5QVS.js.map → chunk-YWBUORD7.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,6 +745,8 @@ 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":
|
|
742
752
|
case "backreference":
|
|
@@ -744,7 +754,7 @@ function measureNode(node) {
|
|
|
744
754
|
case "characterClass": {
|
|
745
755
|
let usage = 5 + node.items.length;
|
|
746
756
|
for (const item of node.items) {
|
|
747
|
-
usage += item.type === "character" ? 3 + item.value.length : item.type === "range" ? 4 + item.from.length + item.to.length : 4;
|
|
757
|
+
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 : 4;
|
|
748
758
|
}
|
|
749
759
|
return usage;
|
|
750
760
|
}
|
|
@@ -756,7 +766,7 @@ function measureNode(node) {
|
|
|
756
766
|
return usage;
|
|
757
767
|
}
|
|
758
768
|
case "group":
|
|
759
|
-
return 5 + measureNode(node.body);
|
|
769
|
+
return 5 + measureNode(node.body) + (node.name === void 0 ? 0 : 1 + node.name.length);
|
|
760
770
|
case "lookahead":
|
|
761
771
|
case "lookbehind":
|
|
762
772
|
return 4 + measureNode(node.body);
|
|
@@ -2049,6 +2059,8 @@ function createIdentifier(token, name) {
|
|
|
2049
2059
|
}
|
|
2050
2060
|
|
|
2051
2061
|
// packages/safe-js/src/interp/regex/parse.ts
|
|
2062
|
+
var groupNameStart = /^[$_\p{ID_Start}]$/u;
|
|
2063
|
+
var groupNamePart = /^[$\u200c\u200d\p{ID_Continue}]$/u;
|
|
2052
2064
|
function parseRegex(source, flags = "", compilation, valueUnits = 0) {
|
|
2053
2065
|
const guard = new RegexCompileGuard(compilation);
|
|
2054
2066
|
try {
|
|
@@ -2056,10 +2068,11 @@ function parseRegex(source, flags = "", compilation, valueUnits = 0) {
|
|
|
2056
2068
|
guard.checkLength(flags.length, true);
|
|
2057
2069
|
guard.allocate(5 + valueUnits);
|
|
2058
2070
|
const parsedFlags = parseFlags(flags, guard);
|
|
2059
|
-
const parser = new RegexParser(source, guard);
|
|
2071
|
+
const parser = new RegexParser(source, guard, parsedFlags.unicode);
|
|
2060
2072
|
const body = parser.parse();
|
|
2061
2073
|
guard.allocate(5 + source.length);
|
|
2062
2074
|
const pattern = { source, flags: parsedFlags, captureCount: parser.captureCount, body };
|
|
2075
|
+
if (Object.keys(parser.namedGroups).length > 0) pattern.groups = parser.namedGroups;
|
|
2063
2076
|
guard.retain(pattern, valueUnits);
|
|
2064
2077
|
return pattern;
|
|
2065
2078
|
} finally {
|
|
@@ -2067,15 +2080,19 @@ function parseRegex(source, flags = "", compilation, valueUnits = 0) {
|
|
|
2067
2080
|
}
|
|
2068
2081
|
}
|
|
2069
2082
|
var RegexParser = class {
|
|
2070
|
-
constructor(source, guard) {
|
|
2083
|
+
constructor(source, guard, unicode) {
|
|
2071
2084
|
this.source = source;
|
|
2072
2085
|
this.guard = guard;
|
|
2086
|
+
this.unicode = unicode;
|
|
2073
2087
|
}
|
|
2074
2088
|
source;
|
|
2075
2089
|
guard;
|
|
2090
|
+
unicode;
|
|
2076
2091
|
captureCount = 0;
|
|
2077
2092
|
cursor = 0;
|
|
2078
2093
|
totalCaptureCount;
|
|
2094
|
+
hasNamedCaptures = false;
|
|
2095
|
+
namedGroups = /* @__PURE__ */ Object.create(null);
|
|
2079
2096
|
get position() {
|
|
2080
2097
|
return this.cursor;
|
|
2081
2098
|
}
|
|
@@ -2091,6 +2108,7 @@ var RegexParser = class {
|
|
|
2091
2108
|
}
|
|
2092
2109
|
this.fail(`Unexpected character '${this.peek()}'`);
|
|
2093
2110
|
}
|
|
2111
|
+
if (this.unicode || Object.keys(this.namedGroups).length > 0) this.validateNamedGroups(body);
|
|
2094
2112
|
return body;
|
|
2095
2113
|
}
|
|
2096
2114
|
parseAlternation() {
|
|
@@ -2132,7 +2150,7 @@ var RegexParser = class {
|
|
|
2132
2150
|
if (quantifier === void 0) {
|
|
2133
2151
|
return body;
|
|
2134
2152
|
}
|
|
2135
|
-
if (body.type === "anchor" || body.type === "wordBoundary" || body.type === "lookbehind") {
|
|
2153
|
+
if (body.type === "anchor" || body.type === "wordBoundary" || body.type === "lookbehind" || this.unicode && body.type === "lookahead") {
|
|
2136
2154
|
this.fail("Invalid quantifier target", quantifierStart);
|
|
2137
2155
|
}
|
|
2138
2156
|
const greedy = this.peek() !== "?";
|
|
@@ -2143,7 +2161,7 @@ var RegexParser = class {
|
|
|
2143
2161
|
return { type: "quantifier", body, ...quantifier, greedy };
|
|
2144
2162
|
}
|
|
2145
2163
|
parseAtom() {
|
|
2146
|
-
const character = this.
|
|
2164
|
+
const character = this.takeCharacter();
|
|
2147
2165
|
switch (character) {
|
|
2148
2166
|
case ".":
|
|
2149
2167
|
this.guard.allocate(2);
|
|
@@ -2161,12 +2179,14 @@ var RegexParser = class {
|
|
|
2161
2179
|
case "\\":
|
|
2162
2180
|
return this.parseEscape(false, this.position - 1);
|
|
2163
2181
|
default:
|
|
2182
|
+
if (this.unicode && (character === "]" || character === "}")) this.fail("Invalid Unicode pattern character");
|
|
2164
2183
|
this.guard.allocate(3 + character.length);
|
|
2165
2184
|
return { type: "literal", value: character };
|
|
2166
2185
|
}
|
|
2167
2186
|
}
|
|
2168
2187
|
parseGroup(start) {
|
|
2169
2188
|
let capturing = true;
|
|
2189
|
+
let name;
|
|
2170
2190
|
let assertionNegated;
|
|
2171
2191
|
let lookbehind = false;
|
|
2172
2192
|
if (this.peek() === "?") {
|
|
@@ -2186,13 +2206,20 @@ var RegexParser = class {
|
|
|
2186
2206
|
lookbehind = true;
|
|
2187
2207
|
this.position += 3;
|
|
2188
2208
|
} else if (extension.startsWith("?<")) {
|
|
2189
|
-
this.
|
|
2209
|
+
this.position += 2;
|
|
2210
|
+
name = this.parseGroupName(start);
|
|
2190
2211
|
} else {
|
|
2191
2212
|
this.fail("Unsupported group construct", start);
|
|
2192
2213
|
}
|
|
2193
2214
|
}
|
|
2194
2215
|
if (capturing) this.guard.allocate(1);
|
|
2195
2216
|
const index = capturing ? ++this.captureCount : void 0;
|
|
2217
|
+
if (name !== void 0) {
|
|
2218
|
+
this.guard.allocate(name.length + 2);
|
|
2219
|
+
const indices = this.namedGroups[name] ??= [];
|
|
2220
|
+
this.guard.array(indices.length + 1);
|
|
2221
|
+
indices.push(index);
|
|
2222
|
+
}
|
|
2196
2223
|
this.guard.enterGroup();
|
|
2197
2224
|
let body;
|
|
2198
2225
|
try {
|
|
@@ -2209,7 +2236,7 @@ var RegexParser = class {
|
|
|
2209
2236
|
return { type: lookbehind ? "lookbehind" : "lookahead", negated: assertionNegated, body };
|
|
2210
2237
|
}
|
|
2211
2238
|
this.guard.allocate(5);
|
|
2212
|
-
return { type: "group", capturing, index, body };
|
|
2239
|
+
return { type: "group", capturing, index, body, ...name === void 0 ? {} : { name } };
|
|
2213
2240
|
}
|
|
2214
2241
|
parseCharacterClass(start) {
|
|
2215
2242
|
const negated = this.peek() === "^";
|
|
@@ -2233,7 +2260,7 @@ var RegexParser = class {
|
|
|
2233
2260
|
if (left.type !== "character" || right.type !== "character") {
|
|
2234
2261
|
this.fail("Character class ranges require literal endpoints", rangePosition);
|
|
2235
2262
|
}
|
|
2236
|
-
if (left.value.
|
|
2263
|
+
if (left.value.codePointAt(0) > right.value.codePointAt(0)) {
|
|
2237
2264
|
this.fail("Character class range is out of order", rangePosition);
|
|
2238
2265
|
}
|
|
2239
2266
|
this.guard.allocate(4 + left.value.length + right.value.length);
|
|
@@ -2262,13 +2289,22 @@ var RegexParser = class {
|
|
|
2262
2289
|
this.fail("Unsupported character class escape", escapeStart);
|
|
2263
2290
|
}
|
|
2264
2291
|
this.guard.allocate(4);
|
|
2265
|
-
return { type: "character", value: this.
|
|
2292
|
+
return { type: "character", value: this.takeCharacter() };
|
|
2266
2293
|
}
|
|
2267
2294
|
parseEscape(inCharacterClass, start) {
|
|
2268
2295
|
if (this.atEnd()) {
|
|
2269
2296
|
this.fail("Trailing escape", start);
|
|
2270
2297
|
}
|
|
2271
2298
|
const escaped = this.take();
|
|
2299
|
+
if (escaped === "k") {
|
|
2300
|
+
this.totalCaptureCount ??= this.countAllCaptures();
|
|
2301
|
+
if (this.unicode || this.hasNamedCaptures) {
|
|
2302
|
+
if (inCharacterClass || this.take() !== "<") this.fail("Invalid named backreference", start);
|
|
2303
|
+
const name = this.parseGroupName(start);
|
|
2304
|
+
this.guard.allocate(3 + name.length);
|
|
2305
|
+
return { type: "namedBackreference", name };
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2272
2308
|
if (isDecimalDigit2(escaped)) {
|
|
2273
2309
|
if (!inCharacterClass && escaped !== "0") {
|
|
2274
2310
|
let end = this.position;
|
|
@@ -2284,6 +2320,8 @@ var RegexParser = class {
|
|
|
2284
2320
|
return { type: "backreference", index };
|
|
2285
2321
|
}
|
|
2286
2322
|
}
|
|
2323
|
+
if (this.unicode && (escaped !== "0" || isDecimalDigit2(this.peek())))
|
|
2324
|
+
this.fail("Invalid decimal escape", start);
|
|
2287
2325
|
this.guard.allocate(4);
|
|
2288
2326
|
if (escaped === "8" || escaped === "9") return { type: "literal", value: escaped };
|
|
2289
2327
|
let code = Number(escaped);
|
|
@@ -2294,7 +2332,24 @@ var RegexParser = class {
|
|
|
2294
2332
|
return { type: "literal", value: String.fromCharCode(code) };
|
|
2295
2333
|
}
|
|
2296
2334
|
if (escaped === "p" || escaped === "P") {
|
|
2297
|
-
this.fail("Unicode property escapes are not supported", start);
|
|
2335
|
+
if (!this.unicode) this.fail("Unicode property escapes are not supported", start);
|
|
2336
|
+
if (this.take() !== "{") this.fail("Invalid Unicode property escape", start);
|
|
2337
|
+
const begin = this.position;
|
|
2338
|
+
while (!this.atEnd() && this.peek() !== "}") {
|
|
2339
|
+
const character = this.take();
|
|
2340
|
+
if (!isDecimalDigit2(character) && !(character >= "a" && character <= "z") && !(character >= "A" && character <= "Z") && character !== "_" && character !== "=")
|
|
2341
|
+
this.fail("Invalid Unicode property escape", start);
|
|
2342
|
+
}
|
|
2343
|
+
this.guard.allocate(this.position - begin + 9);
|
|
2344
|
+
const value = this.source.slice(begin, this.position);
|
|
2345
|
+
if (this.take() !== "}") this.fail("Unterminated Unicode property escape", start);
|
|
2346
|
+
try {
|
|
2347
|
+
new RegExp(`\\p{${value}}`, "u");
|
|
2348
|
+
} catch {
|
|
2349
|
+
this.fail("Unknown Unicode property", start);
|
|
2350
|
+
}
|
|
2351
|
+
this.guard.array(1);
|
|
2352
|
+
return { type: "characterClass", negated: false, items: [{ type: "property", value, negated: escaped === "P" }] };
|
|
2298
2353
|
}
|
|
2299
2354
|
if (escaped === "x") {
|
|
2300
2355
|
this.guard.allocate(4);
|
|
@@ -2302,7 +2357,29 @@ var RegexParser = class {
|
|
|
2302
2357
|
}
|
|
2303
2358
|
if (escaped === "u") {
|
|
2304
2359
|
this.guard.allocate(4);
|
|
2305
|
-
|
|
2360
|
+
if (this.unicode && this.peek() === "{") {
|
|
2361
|
+
this.position++;
|
|
2362
|
+
const begin = this.position;
|
|
2363
|
+
while (!this.atEnd() && this.peek() !== "}") this.position++;
|
|
2364
|
+
this.guard.allocate(this.position - begin);
|
|
2365
|
+
const digits = this.source.slice(begin, this.position);
|
|
2366
|
+
const point = Number.parseInt(digits, 16);
|
|
2367
|
+
if (this.take() !== "}" || digits.length === 0 || !allHexDigits(digits) || point > 1114111)
|
|
2368
|
+
this.fail("Invalid Unicode escape", start);
|
|
2369
|
+
return { type: "literal", value: String.fromCodePoint(point) };
|
|
2370
|
+
}
|
|
2371
|
+
let value = this.parseHexEscape(4, "Unicode", start);
|
|
2372
|
+
if (this.unicode && value.charCodeAt(0) >= 55296 && value.charCodeAt(0) <= 56319 && this.source.startsWith("\\u", this.position)) {
|
|
2373
|
+
const digits = this.source.slice(this.position + 2, this.position + 6);
|
|
2374
|
+
const point = Number.parseInt(digits, 16);
|
|
2375
|
+
this.guard.work(digits.length);
|
|
2376
|
+
this.guard.allocate(digits.length);
|
|
2377
|
+
if (digits.length === 4 && allHexDigits(digits) && point >= 56320 && point <= 57343) {
|
|
2378
|
+
value += String.fromCharCode(point);
|
|
2379
|
+
this.position += 6;
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
return { type: "literal", value };
|
|
2306
2383
|
}
|
|
2307
2384
|
this.guard.allocate(25);
|
|
2308
2385
|
const kinds = {
|
|
@@ -2333,6 +2410,15 @@ var RegexParser = class {
|
|
|
2333
2410
|
v: "\v",
|
|
2334
2411
|
"0": "\0"
|
|
2335
2412
|
};
|
|
2413
|
+
if (escaped === "c" && this.unicode) {
|
|
2414
|
+
const letter = this.take();
|
|
2415
|
+
if (!(letter >= "a" && letter <= "z") && !(letter >= "A" && letter <= "Z"))
|
|
2416
|
+
this.fail("Invalid control escape", start);
|
|
2417
|
+
this.guard.allocate(4);
|
|
2418
|
+
return { type: "literal", value: String.fromCharCode(letter.charCodeAt(0) % 32) };
|
|
2419
|
+
}
|
|
2420
|
+
if (this.unicode && controls[escaped] === void 0 && !"^$\\.*+?()[]{}|/".includes(escaped) && !(inCharacterClass && escaped === "-"))
|
|
2421
|
+
this.fail("Invalid identity escape", start);
|
|
2336
2422
|
this.guard.allocate(4);
|
|
2337
2423
|
return { type: "literal", value: controls[escaped] ?? escaped };
|
|
2338
2424
|
}
|
|
@@ -2358,10 +2444,62 @@ var RegexParser = class {
|
|
|
2358
2444
|
else if (character === "\\") escaped = true;
|
|
2359
2445
|
else if (character === "[") characterClass = true;
|
|
2360
2446
|
else if (character === "]") characterClass = false;
|
|
2361
|
-
else if (!characterClass && character === "("
|
|
2447
|
+
else if (!characterClass && character === "(") {
|
|
2448
|
+
const named = this.source[index + 1] === "?" && this.source[index + 2] === "<" && this.source[index + 3] !== "=" && this.source[index + 3] !== "!";
|
|
2449
|
+
if (named) this.hasNamedCaptures = true;
|
|
2450
|
+
if (named || this.source[index + 1] !== "?") count++;
|
|
2451
|
+
}
|
|
2362
2452
|
}
|
|
2363
2453
|
return count;
|
|
2364
2454
|
}
|
|
2455
|
+
parseGroupName(start) {
|
|
2456
|
+
let name = "";
|
|
2457
|
+
while (!this.atEnd() && this.peek() !== ">") {
|
|
2458
|
+
let character = this.take();
|
|
2459
|
+
if (character === "\\") {
|
|
2460
|
+
if (this.take() !== "u") this.fail("Invalid group name escape", start);
|
|
2461
|
+
if (this.peek() === "{") {
|
|
2462
|
+
this.position++;
|
|
2463
|
+
const begin = this.position;
|
|
2464
|
+
while (!this.atEnd() && this.peek() !== "}") this.position++;
|
|
2465
|
+
this.guard.allocate(this.position - begin);
|
|
2466
|
+
const digits = this.source.slice(begin, this.position);
|
|
2467
|
+
const point = Number.parseInt(digits, 16);
|
|
2468
|
+
if (this.take() !== "}" || digits.length === 0 || !allHexDigits(digits) || point > 1114111)
|
|
2469
|
+
this.fail("Invalid group name escape", start);
|
|
2470
|
+
character = String.fromCodePoint(point);
|
|
2471
|
+
} else character = this.parseHexEscape(4, "Unicode", start);
|
|
2472
|
+
}
|
|
2473
|
+
this.guard.allocate(character.length);
|
|
2474
|
+
name += character;
|
|
2475
|
+
}
|
|
2476
|
+
if (this.take() !== ">" || name.length === 0) this.fail("Invalid group name", start);
|
|
2477
|
+
let first = true;
|
|
2478
|
+
for (const character of name) {
|
|
2479
|
+
this.guard.work(1);
|
|
2480
|
+
if (!(first ? groupNameStart : groupNamePart).test(character)) this.fail("Invalid group name", start);
|
|
2481
|
+
first = false;
|
|
2482
|
+
}
|
|
2483
|
+
return name;
|
|
2484
|
+
}
|
|
2485
|
+
validateNamedGroups(node) {
|
|
2486
|
+
this.guard.work(1);
|
|
2487
|
+
this.guard.allocate(1);
|
|
2488
|
+
const names = /* @__PURE__ */ new Set();
|
|
2489
|
+
if (node.type === "namedBackreference" && !Object.hasOwn(this.namedGroups, node.name))
|
|
2490
|
+
this.fail("Unknown named backreference");
|
|
2491
|
+
if (node.type === "group" && node.name !== void 0) names.add(node.name);
|
|
2492
|
+
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] : [];
|
|
2493
|
+
for (const child of children) {
|
|
2494
|
+
for (const name of this.validateNamedGroups(child)) {
|
|
2495
|
+
this.guard.work(1);
|
|
2496
|
+
if (names.has(name) && node.type !== "alternation") this.fail("Duplicate capture group name");
|
|
2497
|
+
this.guard.allocate(1);
|
|
2498
|
+
names.add(name);
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
return names;
|
|
2502
|
+
}
|
|
2365
2503
|
parseQuantifier() {
|
|
2366
2504
|
const character = this.peek();
|
|
2367
2505
|
if (character === "*") {
|
|
@@ -2433,6 +2571,12 @@ var RegexParser = class {
|
|
|
2433
2571
|
this.position += 1;
|
|
2434
2572
|
return character;
|
|
2435
2573
|
}
|
|
2574
|
+
takeCharacter() {
|
|
2575
|
+
if (!this.unicode || this.atEnd()) return this.take();
|
|
2576
|
+
const character = String.fromCodePoint(this.source.codePointAt(this.position));
|
|
2577
|
+
this.position += character.length;
|
|
2578
|
+
return character;
|
|
2579
|
+
}
|
|
2436
2580
|
atEnd() {
|
|
2437
2581
|
return this.position >= this.source.length;
|
|
2438
2582
|
}
|
|
@@ -2446,6 +2590,7 @@ function parseFlags(flags, guard) {
|
|
|
2446
2590
|
hasIndices: false,
|
|
2447
2591
|
global: false,
|
|
2448
2592
|
sticky: false,
|
|
2593
|
+
unicode: false,
|
|
2449
2594
|
ignoreCase: false,
|
|
2450
2595
|
multiline: false,
|
|
2451
2596
|
dotAll: false
|
|
@@ -2456,7 +2601,8 @@ function parseFlags(flags, guard) {
|
|
|
2456
2601
|
i: "ignoreCase",
|
|
2457
2602
|
m: "multiline",
|
|
2458
2603
|
s: "dotAll",
|
|
2459
|
-
y: "sticky"
|
|
2604
|
+
y: "sticky",
|
|
2605
|
+
u: "unicode"
|
|
2460
2606
|
};
|
|
2461
2607
|
for (let position = 0; position < flags.length; position += 1) {
|
|
2462
2608
|
guard.work(1);
|
|
@@ -9372,8 +9518,9 @@ function matchRegexFrom(pattern, input, startIndex) {
|
|
|
9372
9518
|
if (startIndex > input.length) {
|
|
9373
9519
|
return null;
|
|
9374
9520
|
}
|
|
9375
|
-
|
|
9376
|
-
|
|
9521
|
+
if (pattern.flags.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--;
|
|
9522
|
+
for (let attempt = startIndex; attempt <= input.length; attempt = advanceStringIndex(input, attempt, pattern.flags.unicode)) {
|
|
9523
|
+
const context = { input, flags: pattern.flags, groups: pattern.groups, direction: 1, work: { steps: 0 } };
|
|
9377
9524
|
charge(context);
|
|
9378
9525
|
const initialState = {
|
|
9379
9526
|
position: attempt,
|
|
@@ -9381,7 +9528,7 @@ function matchRegexFrom(pattern, input, startIndex) {
|
|
|
9381
9528
|
};
|
|
9382
9529
|
const result = matchNode(pattern.body, initialState, context).next();
|
|
9383
9530
|
if (!result.done) {
|
|
9384
|
-
return toRegexMatch(input, attempt, result.value, pattern.flags.hasIndices);
|
|
9531
|
+
return toRegexMatch(input, attempt, result.value, pattern.flags.hasIndices, pattern.groups);
|
|
9385
9532
|
}
|
|
9386
9533
|
if (pattern.flags.sticky) break;
|
|
9387
9534
|
}
|
|
@@ -9389,35 +9536,50 @@ function matchRegexFrom(pattern, input, startIndex) {
|
|
|
9389
9536
|
}
|
|
9390
9537
|
function* matchNode(node, state, context) {
|
|
9391
9538
|
charge(context);
|
|
9392
|
-
const
|
|
9539
|
+
const character = readCharacter(context.input, state.position, context.direction, context.flags.unicode);
|
|
9393
9540
|
switch (node.type) {
|
|
9394
9541
|
case "empty":
|
|
9395
9542
|
yield state;
|
|
9396
9543
|
return;
|
|
9397
9544
|
case "literal":
|
|
9398
|
-
if (charactersEqual(
|
|
9399
|
-
yield { ...state, position: state.position + context.direction };
|
|
9545
|
+
if (charactersEqual(character, node.value, context.flags.ignoreCase, context.flags.unicode)) {
|
|
9546
|
+
yield { ...state, position: state.position + context.direction * character.length };
|
|
9400
9547
|
}
|
|
9401
9548
|
return;
|
|
9402
|
-
case "backreference":
|
|
9403
|
-
|
|
9549
|
+
case "backreference":
|
|
9550
|
+
case "namedBackreference": {
|
|
9551
|
+
let capture;
|
|
9552
|
+
if (node.type === "backreference") capture = state.captures[node.index - 1];
|
|
9553
|
+
else {
|
|
9554
|
+
for (const index of context.groups?.[node.name] ?? []) {
|
|
9555
|
+
charge(context);
|
|
9556
|
+
if (state.captures[index - 1] !== void 0) {
|
|
9557
|
+
capture = state.captures[index - 1];
|
|
9558
|
+
break;
|
|
9559
|
+
}
|
|
9560
|
+
}
|
|
9561
|
+
}
|
|
9404
9562
|
if (capture === void 0) {
|
|
9405
9563
|
yield state;
|
|
9406
9564
|
return;
|
|
9407
9565
|
}
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9566
|
+
let position = state.position;
|
|
9567
|
+
let reference = context.direction === 1 ? capture.start : capture.end;
|
|
9568
|
+
const end = context.direction === 1 ? capture.end : capture.start;
|
|
9569
|
+
while (reference !== end) {
|
|
9412
9570
|
charge(context);
|
|
9413
|
-
|
|
9571
|
+
const expected = readCharacter(context.input, reference, context.direction, context.flags.unicode);
|
|
9572
|
+
const actual = readCharacter(context.input, position, context.direction, context.flags.unicode);
|
|
9573
|
+
if (!charactersEqual(actual, expected, context.flags.ignoreCase, context.flags.unicode)) return;
|
|
9574
|
+
reference += context.direction * expected.length;
|
|
9575
|
+
position += context.direction * actual.length;
|
|
9414
9576
|
}
|
|
9415
|
-
yield { ...state, position
|
|
9577
|
+
yield { ...state, position };
|
|
9416
9578
|
return;
|
|
9417
9579
|
}
|
|
9418
9580
|
case "dot":
|
|
9419
|
-
if (
|
|
9420
|
-
yield { ...state, position: state.position + context.direction };
|
|
9581
|
+
if (character !== void 0 && (context.flags.dotAll || !isLineTerminator(character))) {
|
|
9582
|
+
yield { ...state, position: state.position + context.direction * character.length };
|
|
9421
9583
|
}
|
|
9422
9584
|
return;
|
|
9423
9585
|
case "anchor":
|
|
@@ -9426,17 +9588,16 @@ function* matchNode(node, state, context) {
|
|
|
9426
9588
|
}
|
|
9427
9589
|
return;
|
|
9428
9590
|
case "wordBoundary": {
|
|
9429
|
-
const previousWord = state.position > 0 &&
|
|
9430
|
-
const nextWord = state.position < context.input.length &&
|
|
9591
|
+
const previousWord = state.position > 0 && matchesCharacterClassItem(context.input[state.position - 1], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, context.flags.unicode);
|
|
9592
|
+
const nextWord = state.position < context.input.length && matchesCharacterClassItem(context.input[state.position], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, context.flags.unicode);
|
|
9431
9593
|
if (previousWord !== nextWord !== node.negated) {
|
|
9432
9594
|
yield state;
|
|
9433
9595
|
}
|
|
9434
9596
|
return;
|
|
9435
9597
|
}
|
|
9436
9598
|
case "characterClass": {
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
yield { ...state, position: state.position + context.direction };
|
|
9599
|
+
if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context)) {
|
|
9600
|
+
yield { ...state, position: state.position + context.direction * character.length };
|
|
9440
9601
|
}
|
|
9441
9602
|
return;
|
|
9442
9603
|
}
|
|
@@ -9519,11 +9680,27 @@ function matchesAnchor(kind, position, context) {
|
|
|
9519
9680
|
}
|
|
9520
9681
|
return position === context.input.length || context.flags.multiline && position < context.input.length && isLineTerminator(context.input[position]);
|
|
9521
9682
|
}
|
|
9522
|
-
function matchesCharacterClass(character, items, negated,
|
|
9523
|
-
const matched = items.some((item) =>
|
|
9683
|
+
function matchesCharacterClass(character, items, negated, context) {
|
|
9684
|
+
const matched = items.some((item) => {
|
|
9685
|
+
if (context.flags.unicode) charge(context);
|
|
9686
|
+
return matchesCharacterClassItem(character, item, context.flags.ignoreCase, context.flags.unicode);
|
|
9687
|
+
});
|
|
9524
9688
|
return negated ? !matched : matched;
|
|
9525
9689
|
}
|
|
9526
|
-
function matchesCharacterClassItem(character, item, ignoreCase) {
|
|
9690
|
+
function matchesCharacterClassItem(character, item, ignoreCase, unicode) {
|
|
9691
|
+
if (unicode) {
|
|
9692
|
+
const hex = (value) => `\\u{${value.codePointAt(0).toString(16)}}`;
|
|
9693
|
+
let atom;
|
|
9694
|
+
if (item.type === "character") atom = hex(item.value);
|
|
9695
|
+
else if (item.type === "range") atom = `[${hex(item.from)}-${hex(item.to)}]`;
|
|
9696
|
+
else if (item.type === "property") atom = `\\${item.negated ? "P" : "p"}{${item.value}}`;
|
|
9697
|
+
else {
|
|
9698
|
+
const kind = item.kind === "digit" ? "d" : item.kind === "word" ? "w" : "s";
|
|
9699
|
+
atom = `\\${item.negated ? kind.toUpperCase() : kind}`;
|
|
9700
|
+
}
|
|
9701
|
+
return new RegExp(`^(?:${atom})$`, ignoreCase ? "iu" : "u").test(character);
|
|
9702
|
+
}
|
|
9703
|
+
if (item.type === "property") return false;
|
|
9527
9704
|
if (item.type === "character") {
|
|
9528
9705
|
return charactersEqual(character, item.value, ignoreCase);
|
|
9529
9706
|
}
|
|
@@ -9545,7 +9722,7 @@ function matchesCharacterClassItem(character, item, ignoreCase) {
|
|
|
9545
9722
|
const matched = item.kind === "digit" ? isDigit(character) : item.kind === "word" ? isWordCharacter(character) : isSpaceCharacter(character);
|
|
9546
9723
|
return item.negated ? !matched : matched;
|
|
9547
9724
|
}
|
|
9548
|
-
function toRegexMatch(input, start, state, hasIndices) {
|
|
9725
|
+
function toRegexMatch(input, start, state, hasIndices, groups) {
|
|
9549
9726
|
const match = {
|
|
9550
9727
|
index: start,
|
|
9551
9728
|
text: input.slice(start, state.position),
|
|
@@ -9556,6 +9733,15 @@ function toRegexMatch(input, start, state, hasIndices) {
|
|
|
9556
9733
|
if (hasIndices) {
|
|
9557
9734
|
match.indices = [[start, state.position], ...state.captures.map((capture) => capture === void 0 ? void 0 : [capture.start, capture.end])];
|
|
9558
9735
|
}
|
|
9736
|
+
if (groups !== void 0) {
|
|
9737
|
+
match.groups = /* @__PURE__ */ Object.create(null);
|
|
9738
|
+
if (hasIndices) match.indicesGroups = /* @__PURE__ */ Object.create(null);
|
|
9739
|
+
for (const [name, indices] of Object.entries(groups)) {
|
|
9740
|
+
const index = indices.find((index2) => state.captures[index2 - 1] !== void 0);
|
|
9741
|
+
match.groups[name] = index === void 0 ? void 0 : match.captures[index - 1];
|
|
9742
|
+
if (match.indicesGroups !== void 0) match.indicesGroups[name] = index === void 0 ? void 0 : match.indices[index];
|
|
9743
|
+
}
|
|
9744
|
+
}
|
|
9559
9745
|
return match;
|
|
9560
9746
|
}
|
|
9561
9747
|
function cloneState(state) {
|
|
@@ -9600,9 +9786,20 @@ function normalizeLastIndex(lastIndex) {
|
|
|
9600
9786
|
}
|
|
9601
9787
|
return Math.min(Math.floor(lastIndex), Number.MAX_SAFE_INTEGER);
|
|
9602
9788
|
}
|
|
9603
|
-
function charactersEqual(left, right, ignoreCase) {
|
|
9789
|
+
function charactersEqual(left, right, ignoreCase, unicode = false) {
|
|
9790
|
+
if (unicode && ignoreCase && left !== void 0)
|
|
9791
|
+
return new RegExp(`^\\u{${right.codePointAt(0).toString(16)}}$`, "iu").test(left);
|
|
9604
9792
|
return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
|
|
9605
9793
|
}
|
|
9794
|
+
function advanceStringIndex(input, index, unicode) {
|
|
9795
|
+
return index + (unicode && (input.codePointAt(index) ?? 0) > 65535 ? 2 : 1);
|
|
9796
|
+
}
|
|
9797
|
+
function readCharacter(input, position, direction, unicode) {
|
|
9798
|
+
let index = direction === 1 ? position : position - 1;
|
|
9799
|
+
if (index < 0 || index >= input.length) return void 0;
|
|
9800
|
+
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--;
|
|
9801
|
+
return unicode ? String.fromCodePoint(input.codePointAt(index)) : input[index];
|
|
9802
|
+
}
|
|
9606
9803
|
function foldCharacter(character, ignoreCase) {
|
|
9607
9804
|
if (!ignoreCase) {
|
|
9608
9805
|
return character;
|
|
@@ -10178,7 +10375,7 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, use
|
|
|
10178
10375
|
);
|
|
10179
10376
|
}
|
|
10180
10377
|
async function replaceRegex(value, regex, replacement, budget, callClosure, context) {
|
|
10181
|
-
if (hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget))
|
|
10378
|
+
if (getSandboxRegexPattern(regex).groups !== void 0 || hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget))
|
|
10182
10379
|
return regexReplace(value, regex, replacement, budget, callClosure, context);
|
|
10183
10380
|
if (regex.flags.includes("g")) regex.lastIndex = 0;
|
|
10184
10381
|
const cursor = regex.lastIndex;
|
|
@@ -10228,7 +10425,7 @@ async function regexReplace(input, regex, replacementInput, budget, callClosure,
|
|
|
10228
10425
|
input = void 0;
|
|
10229
10426
|
replacement = isSandboxClosure(replacementInput) ? replacementInput : await sandboxString(replacementInput, budget, context);
|
|
10230
10427
|
replacementInput = void 0;
|
|
10231
|
-
if (isSandboxRegex(regex) && !hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget)) {
|
|
10428
|
+
if (isSandboxRegex(regex) && getSandboxRegexPattern(regex).groups === void 0 && !hasRegexPropertyOverride(regex, ["exec", "flags", ...Object.keys(regexFlagProperties)], budget)) {
|
|
10232
10429
|
release();
|
|
10233
10430
|
return await replaceRegex(value, regex, replacement, budget, callClosure, context);
|
|
10234
10431
|
}
|
|
@@ -10443,7 +10640,7 @@ function splitNormalized(value, separator, limit, budget, parent) {
|
|
|
10443
10640
|
while (result2.length < limit) {
|
|
10444
10641
|
const match = executeRegex(splitter, value, Number(splitter.lastIndex));
|
|
10445
10642
|
if (match === null) break;
|
|
10446
|
-
if (match.text.length === 0) splitter.lastIndex = match.index
|
|
10643
|
+
if (match.text.length === 0) splitter.lastIndex = advanceStringIndex(value, match.index, splitter.flags.includes("u"));
|
|
10447
10644
|
endedWithZeroWidthMatch = match.text.length === 0 && match.index === value.length;
|
|
10448
10645
|
if (match.text.length === 0 && (match.index === copiedThrough || match.index === value.length))
|
|
10449
10646
|
continue;
|
|
@@ -10618,7 +10815,7 @@ function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
|
|
|
10618
10815
|
budget?.allocateArrayLength(matches.length + 1);
|
|
10619
10816
|
matches.push(match);
|
|
10620
10817
|
lastIndex = match.index + match.text.length;
|
|
10621
|
-
if (all && match.text.length === 0) regex.lastIndex =
|
|
10818
|
+
if (all && match.text.length === 0) regex.lastIndex = lastIndex = advanceStringIndex(value, lastIndex, regex.flags.includes("u"));
|
|
10622
10819
|
} while (all);
|
|
10623
10820
|
return matches;
|
|
10624
10821
|
}
|
|
@@ -16829,11 +17026,13 @@ function toMatchArray(match, input, budget) {
|
|
|
16829
17026
|
}
|
|
16830
17027
|
budget?.allocateArrayLength(match.captures.length + 1);
|
|
16831
17028
|
const result = [match.text, ...match.captures];
|
|
16832
|
-
|
|
17029
|
+
if (match.groups !== void 0) setSandboxPrototype(match.groups, null, budget);
|
|
17030
|
+
if (match.indicesGroups !== void 0) setSandboxPrototype(match.indicesGroups, null, budget);
|
|
17031
|
+
Object.assign(result, { index: match.index, input, groups: match.groups });
|
|
16833
17032
|
if (match.indices !== void 0) {
|
|
16834
17033
|
budget?.allocateArrayLength(match.indices.length);
|
|
16835
17034
|
budget?.allocateArrayLength(2);
|
|
16836
|
-
Object.assign(match.indices, { groups:
|
|
17035
|
+
Object.assign(match.indices, { groups: match.indicesGroups });
|
|
16837
17036
|
Object.assign(result, { indices: match.indices });
|
|
16838
17037
|
}
|
|
16839
17038
|
return result;
|
|
@@ -37182,4 +37381,4 @@ export {
|
|
|
37182
37381
|
FileSnapshotBackend,
|
|
37183
37382
|
run
|
|
37184
37383
|
};
|
|
37185
|
-
//# sourceMappingURL=chunk-
|
|
37384
|
+
//# sourceMappingURL=chunk-X5VIB5JV.js.map
|