regex-inspector 1.0.1
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/LICENSE +21 -0
- package/README.md +164 -0
- package/bin/regex-inspector.js +137 -0
- package/dist/analyze.d.ts +19 -0
- package/dist/analyze.d.ts.map +1 -0
- package/dist/analyze.js +608 -0
- package/dist/analyze.js.map +1 -0
- package/dist/ast.d.ts +108 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +5 -0
- package/dist/ast.js.map +1 -0
- package/dist/fix.d.ts +12 -0
- package/dist/fix.d.ts.map +1 -0
- package/dist/fix.js +169 -0
- package/dist/fix.js.map +1 -0
- package/dist/generator.d.ts +7 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +191 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +3 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +776 -0
- package/dist/parser.js.map +1 -0
- package/dist/preset.d.ts +39 -0
- package/dist/preset.d.ts.map +1 -0
- package/dist/preset.js +96 -0
- package/dist/preset.js.map +1 -0
- package/package.json +78 -0
package/dist/analyze.js
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
// ── Token leaf extraction ─────────────────────────────────────────────────
|
|
2
|
+
function getFirstLeaf(node) {
|
|
3
|
+
if (node.kind === "char" ||
|
|
4
|
+
node.kind === "charset" ||
|
|
5
|
+
node.kind === "unicode_property")
|
|
6
|
+
return node;
|
|
7
|
+
if (node.kind === "repetition")
|
|
8
|
+
return getFirstLeaf(node.child);
|
|
9
|
+
if (node.kind === "group") {
|
|
10
|
+
const firstBranch = node.branches[0];
|
|
11
|
+
if (firstBranch && firstBranch.length > 0) {
|
|
12
|
+
return getFirstLeaf(firstBranch[0]);
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
function getAllFirstLeaves(node) {
|
|
19
|
+
if (node.kind === "char" ||
|
|
20
|
+
node.kind === "charset" ||
|
|
21
|
+
node.kind === "unicode_property")
|
|
22
|
+
return [node];
|
|
23
|
+
if (node.kind === "repetition")
|
|
24
|
+
return getAllFirstLeaves(node.child);
|
|
25
|
+
if (node.kind === "group") {
|
|
26
|
+
const leaves = [];
|
|
27
|
+
for (const branch of node.branches) {
|
|
28
|
+
if (branch.length > 0) {
|
|
29
|
+
leaves.push(...getAllFirstLeaves(branch[0]));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return leaves;
|
|
33
|
+
}
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
function isNonOptional(node) {
|
|
37
|
+
if (node.kind === "char" ||
|
|
38
|
+
node.kind === "charset" ||
|
|
39
|
+
node.kind === "unicode_property")
|
|
40
|
+
return true;
|
|
41
|
+
if (node.kind === "position" || node.kind === "backreference")
|
|
42
|
+
return false;
|
|
43
|
+
if (node.kind === "repetition")
|
|
44
|
+
return node.min >= 1;
|
|
45
|
+
if (node.kind === "group") {
|
|
46
|
+
for (const branch of node.branches) {
|
|
47
|
+
if (branch.length === 0 || !isNonOptional(branch[0]))
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return node.branches.length > 0;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// ── Character set overlap ─────────────────────────────────────────────────
|
|
55
|
+
function codeInMembers(cp, members) {
|
|
56
|
+
for (const m of members) {
|
|
57
|
+
if (m.kind === "char" && m.value === cp)
|
|
58
|
+
return true;
|
|
59
|
+
if (m.kind === "range" && cp >= m.from && cp <= m.to)
|
|
60
|
+
return true;
|
|
61
|
+
if (m.kind === "charset") {
|
|
62
|
+
if (codeMatchesSet(cp, m))
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (m.kind === "string_member") {
|
|
66
|
+
for (const s of m.strings) {
|
|
67
|
+
if (s.length === 1 && s[0] === cp)
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (m.kind === "set_op") {
|
|
72
|
+
const inLeft = codeInMembers(cp, [m.left]);
|
|
73
|
+
const inRight = codeInMembers(cp, [m.right]);
|
|
74
|
+
if (m.operator === "subtract" && inLeft && !inRight)
|
|
75
|
+
return true;
|
|
76
|
+
if (m.operator === "intersect" && inLeft && inRight)
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
// Conservative: can't determine character membership of unicode
|
|
80
|
+
// property escapes. Assume the code point is in the set.
|
|
81
|
+
if (m.kind === "unicode_property")
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
function codeMatchesSet(cp, set) {
|
|
87
|
+
const inEntries = codeInMembers(cp, set.members);
|
|
88
|
+
return set.negated ? !inEntries : inEntries;
|
|
89
|
+
}
|
|
90
|
+
function membersOverlap(a, b) {
|
|
91
|
+
// Conservative: new node types always assume overlap.
|
|
92
|
+
if (a.kind === "string_member" ||
|
|
93
|
+
a.kind === "set_op" ||
|
|
94
|
+
a.kind === "unicode_property" ||
|
|
95
|
+
a.kind === "charset")
|
|
96
|
+
return true;
|
|
97
|
+
if (b.kind === "string_member" ||
|
|
98
|
+
b.kind === "set_op" ||
|
|
99
|
+
b.kind === "unicode_property" ||
|
|
100
|
+
b.kind === "charset")
|
|
101
|
+
return true;
|
|
102
|
+
if (a.kind !== "char" && a.kind !== "range")
|
|
103
|
+
return false;
|
|
104
|
+
if (b.kind !== "char" && b.kind !== "range")
|
|
105
|
+
return false;
|
|
106
|
+
if (a.kind === "range" && b.kind === "range") {
|
|
107
|
+
return a.from <= b.to && b.from <= a.to;
|
|
108
|
+
}
|
|
109
|
+
if (a.kind === "char" && b.kind === "char") {
|
|
110
|
+
return a.value === b.value;
|
|
111
|
+
}
|
|
112
|
+
// CHAR vs RANGE
|
|
113
|
+
const charNode = (a.kind === "char" ? a : b);
|
|
114
|
+
const charVal = charNode.value;
|
|
115
|
+
const range = (a.kind === "range" ? a : b);
|
|
116
|
+
return charVal >= range.from && charVal <= range.to;
|
|
117
|
+
}
|
|
118
|
+
function setsOverlap(a, b) {
|
|
119
|
+
if (a.negated && b.negated)
|
|
120
|
+
return true;
|
|
121
|
+
if (a.negated !== b.negated) {
|
|
122
|
+
const pos = a.negated ? b : a;
|
|
123
|
+
const neg = a.negated ? a : b;
|
|
124
|
+
for (const m of pos.members) {
|
|
125
|
+
if (m.kind === "char") {
|
|
126
|
+
if (!codeInMembers(m.value, neg.members))
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
else if (m.kind === "range") {
|
|
130
|
+
if (!codeInMembers(m.from, neg.members))
|
|
131
|
+
return true;
|
|
132
|
+
if (m.from !== m.to && !codeInMembers(m.to, neg.members))
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
else if (m.kind === "string_member" ||
|
|
136
|
+
m.kind === "set_op" ||
|
|
137
|
+
m.kind === "unicode_property") {
|
|
138
|
+
// Conservative: new node types may expand beyond the negated set
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
else if (m.kind === "charset") {
|
|
142
|
+
// Nested charset inside positive set.
|
|
143
|
+
// If negated, conservatively assume overlap.
|
|
144
|
+
if (m.negated)
|
|
145
|
+
return true;
|
|
146
|
+
for (const sm of m.members) {
|
|
147
|
+
if (sm.kind === "char") {
|
|
148
|
+
if (!codeInMembers(sm.value, neg.members))
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
else if (sm.kind === "range") {
|
|
152
|
+
if (!codeInMembers(sm.from, neg.members))
|
|
153
|
+
return true;
|
|
154
|
+
if (sm.from !== sm.to && !codeInMembers(sm.to, neg.members))
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Deeper nesting: conservatively assume overlap
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
for (const ma of a.members) {
|
|
167
|
+
for (const mb of b.members) {
|
|
168
|
+
if (membersOverlap(ma, mb))
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
function tokensOverlap(a, b) {
|
|
175
|
+
// Conservative: can't determine character membership of unicode property
|
|
176
|
+
// escapes without full Unicode data. Assume overlap.
|
|
177
|
+
if (a.kind === "unicode_property" || b.kind === "unicode_property")
|
|
178
|
+
return true;
|
|
179
|
+
if (a.kind === "char" && b.kind === "char")
|
|
180
|
+
return a.value === b.value;
|
|
181
|
+
if (a.kind === "char" && b.kind === "charset")
|
|
182
|
+
return codeMatchesSet(a.value, b);
|
|
183
|
+
if (a.kind === "charset" && b.kind === "char")
|
|
184
|
+
return codeMatchesSet(b.value, a);
|
|
185
|
+
if (a.kind === "charset" && b.kind === "charset")
|
|
186
|
+
return setsOverlap(a, b);
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
// ── Unambiguous nested repetition ─────────────────────────────────────────
|
|
190
|
+
function isUnambiguous(node) {
|
|
191
|
+
let branches;
|
|
192
|
+
if (node.kind === "group") {
|
|
193
|
+
branches = node.branches;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
branches = [[node]];
|
|
197
|
+
}
|
|
198
|
+
for (const branch of branches) {
|
|
199
|
+
if (branch.length === 0)
|
|
200
|
+
return false;
|
|
201
|
+
const first = branch[0];
|
|
202
|
+
if (!isNonOptional(first))
|
|
203
|
+
return false;
|
|
204
|
+
// Single-branch single-token: can't be unambiguous (classic nested rep).
|
|
205
|
+
// Multi-branch single-token: within-branch check is N/A; rely on
|
|
206
|
+
// cross-branch overlap check below.
|
|
207
|
+
if (branch.length < 2) {
|
|
208
|
+
if (branches.length === 1)
|
|
209
|
+
return false;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const firstLeaves = getAllFirstLeaves(first);
|
|
213
|
+
const secondLeaf = getFirstLeaf(branch[1]);
|
|
214
|
+
if (firstLeaves.length === 0 || !secondLeaf)
|
|
215
|
+
return false;
|
|
216
|
+
for (const leaf of firstLeaves) {
|
|
217
|
+
if (tokensOverlap(leaf, secondLeaf))
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (branches.length > 1) {
|
|
222
|
+
const allFirsts = branches.map((b) => getAllFirstLeaves(b[0]));
|
|
223
|
+
for (let i = 0; i < allFirsts.length; i++) {
|
|
224
|
+
for (let j = i + 1; j < allFirsts.length; j++) {
|
|
225
|
+
for (const ai of allFirsts[i]) {
|
|
226
|
+
for (const bj of allFirsts[j]) {
|
|
227
|
+
if (tokensOverlap(ai, bj))
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
// ── Alternation overlap detection ─────────────────────────────────────────
|
|
237
|
+
function getPrefixTokens(branch) {
|
|
238
|
+
const tokens = [];
|
|
239
|
+
for (const t of branch) {
|
|
240
|
+
if (t.kind === "char" ||
|
|
241
|
+
t.kind === "charset" ||
|
|
242
|
+
t.kind === "unicode_property") {
|
|
243
|
+
tokens.push(t);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
// Repetition with min >= 1 has a mandatory first character;
|
|
247
|
+
// extract the first leaf of its child as the effective prefix token.
|
|
248
|
+
if (t.kind === "repetition" && t.min >= 1) {
|
|
249
|
+
const leaf = getFirstLeaf(t.child);
|
|
250
|
+
if (leaf) {
|
|
251
|
+
tokens.push(leaf);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
return tokens;
|
|
258
|
+
}
|
|
259
|
+
function hasAlternationReDoS(branches) {
|
|
260
|
+
if (branches.length < 2)
|
|
261
|
+
return false;
|
|
262
|
+
const prefixes = branches
|
|
263
|
+
.map((b) => getPrefixTokens(b))
|
|
264
|
+
.filter((p) => p.length > 0);
|
|
265
|
+
if (prefixes.length < 2)
|
|
266
|
+
return false;
|
|
267
|
+
for (let i = 0; i < prefixes.length; i++) {
|
|
268
|
+
for (let j = i + 1; j < prefixes.length; j++) {
|
|
269
|
+
const a = prefixes[i];
|
|
270
|
+
const b = prefixes[j];
|
|
271
|
+
const shorter = a.length <= b.length ? a : b;
|
|
272
|
+
const longer = a.length <= b.length ? b : a;
|
|
273
|
+
let prefixMatch = true;
|
|
274
|
+
for (let k = 0; k < shorter.length; k++) {
|
|
275
|
+
if (!tokensOverlap(shorter[k], longer[k])) {
|
|
276
|
+
prefixMatch = false;
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (prefixMatch)
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
function findAlternationReDoS(node) {
|
|
287
|
+
if (!node || typeof node !== "object" || !("kind" in node))
|
|
288
|
+
return false;
|
|
289
|
+
const n = node;
|
|
290
|
+
if (n.kind === "group" && hasAlternationReDoS(n.branches))
|
|
291
|
+
return true;
|
|
292
|
+
if (n.kind === "root" || n.kind === "group") {
|
|
293
|
+
const branches = n.kind === "root" ? n.branches : n.branches;
|
|
294
|
+
for (const branch of branches) {
|
|
295
|
+
for (const child of branch) {
|
|
296
|
+
if (findAlternationReDoS(child))
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (n.kind === "repetition") {
|
|
302
|
+
if (findAlternationReDoS(n.child))
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
// ── Last-leaf extraction ─────────────────────────────────────────────────
|
|
308
|
+
/**
|
|
309
|
+
* Returns the set of tokens that can appear at the end of a match for `node`.
|
|
310
|
+
* Mirrors `getAllFirstLeaves` but for the trailing edge.
|
|
311
|
+
*/
|
|
312
|
+
function getAllLastLeaves(node) {
|
|
313
|
+
if (node.kind === "char" ||
|
|
314
|
+
node.kind === "charset" ||
|
|
315
|
+
node.kind === "unicode_property")
|
|
316
|
+
return [node];
|
|
317
|
+
if (node.kind === "repetition")
|
|
318
|
+
return getAllLastLeaves(node.child);
|
|
319
|
+
if (node.kind === "group") {
|
|
320
|
+
const leaves = [];
|
|
321
|
+
for (const branch of node.branches) {
|
|
322
|
+
if (branch.length > 0) {
|
|
323
|
+
leaves.push(...getAllLastLeaves(branch[branch.length - 1]));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return leaves;
|
|
327
|
+
}
|
|
328
|
+
return [];
|
|
329
|
+
}
|
|
330
|
+
// ── Sequential overlap detection ──────────────────────────────────────────
|
|
331
|
+
/** Returns true when `node` is or contains a repetition (quantifier). */
|
|
332
|
+
function containsRepetition(node) {
|
|
333
|
+
if (node.kind === "repetition")
|
|
334
|
+
return true;
|
|
335
|
+
if (node.kind === "group") {
|
|
336
|
+
for (const branch of node.branches) {
|
|
337
|
+
for (const child of branch) {
|
|
338
|
+
if (containsRepetition(child))
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Checks whether the trailing match domain of token `a` overlaps with the
|
|
347
|
+
* leading match domain of token `b`. Only flagged when `a` is or contains a
|
|
348
|
+
* quantifier; a literal followed by a quantifier does not create the same
|
|
349
|
+
* over-consume risk because the literal cannot expand.
|
|
350
|
+
*/
|
|
351
|
+
function hasDangerAdjacency(a, b) {
|
|
352
|
+
if (!containsRepetition(a))
|
|
353
|
+
return false;
|
|
354
|
+
const lastLeaves = getAllLastLeaves(a);
|
|
355
|
+
const firstLeaves = getAllFirstLeaves(b);
|
|
356
|
+
if (lastLeaves.length === 0 || firstLeaves.length === 0)
|
|
357
|
+
return false;
|
|
358
|
+
for (const la of lastLeaves) {
|
|
359
|
+
for (const fb of firstLeaves) {
|
|
360
|
+
if (tokensOverlap(la, fb))
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Walks the AST looking for branches that contain two or more consecutive
|
|
368
|
+
* quantifier→next-token pairs where the quantifier's charset overlaps the
|
|
369
|
+
* next token's first character. A single such adjacency inside a repeated
|
|
370
|
+
* group is also considered dangerous because the outer repetition amplifies
|
|
371
|
+
* the overlap into exponential backtracking.
|
|
372
|
+
*
|
|
373
|
+
* Examples:
|
|
374
|
+
* .*?B.*?C → 2 adjacencies → flagged
|
|
375
|
+
* (.*?,){11}P → 1 adjacency inside repeated group → flagged
|
|
376
|
+
* a+b+ → 0 adjacencies (a does not overlap b) → safe
|
|
377
|
+
*/
|
|
378
|
+
function findSequentialOverlap(node, insideRepetition) {
|
|
379
|
+
if (node.kind === "repetition") {
|
|
380
|
+
return findSequentialOverlap(node.child, true);
|
|
381
|
+
}
|
|
382
|
+
if (node.kind === "root" || node.kind === "group") {
|
|
383
|
+
const branches = node.kind === "root" ? node.branches : node.branches;
|
|
384
|
+
for (const branch of branches) {
|
|
385
|
+
let dangerCount = 0;
|
|
386
|
+
for (let i = 0; i < branch.length - 1; i++) {
|
|
387
|
+
if (hasDangerAdjacency(branch[i], branch[i + 1])) {
|
|
388
|
+
dangerCount++;
|
|
389
|
+
if (insideRepetition && dangerCount >= 1)
|
|
390
|
+
return true;
|
|
391
|
+
if (dangerCount >= 2)
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
for (const child of branch) {
|
|
396
|
+
if (child.kind === "repetition" &&
|
|
397
|
+
findSequentialOverlap(child.child, true))
|
|
398
|
+
return true;
|
|
399
|
+
if (child.kind === "group" && findSequentialOverlap(child, false))
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
// ── Anchoring and suffix detection ────────────────────────────────────────
|
|
407
|
+
function detectAnchored(root) {
|
|
408
|
+
if (root.kind !== "root")
|
|
409
|
+
return false;
|
|
410
|
+
const branches = root.branches;
|
|
411
|
+
if (branches.length !== 1)
|
|
412
|
+
return false;
|
|
413
|
+
const stack = branches[0];
|
|
414
|
+
if (stack.length < 2)
|
|
415
|
+
return false;
|
|
416
|
+
const first = stack[0];
|
|
417
|
+
const last = stack[stack.length - 1];
|
|
418
|
+
return (first.kind === "position" &&
|
|
419
|
+
first.value === "^" &&
|
|
420
|
+
last.kind === "position" &&
|
|
421
|
+
last.value === "$");
|
|
422
|
+
}
|
|
423
|
+
/** Returns the trailing char/charset token of a single-branch root, or null. */
|
|
424
|
+
function getSuffixToken(root) {
|
|
425
|
+
if (root.kind !== "root")
|
|
426
|
+
return null;
|
|
427
|
+
const branches = root.branches;
|
|
428
|
+
if (branches.length !== 1)
|
|
429
|
+
return null;
|
|
430
|
+
const stack = branches[0];
|
|
431
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
432
|
+
const child = stack[i];
|
|
433
|
+
if (child.kind === "position")
|
|
434
|
+
continue;
|
|
435
|
+
if (child.kind === "char" || child.kind === "charset")
|
|
436
|
+
return child;
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Checks whether any repetition in the AST has a child whose character set
|
|
443
|
+
* overlaps with `suffix`. If so, the suffix does NOT mitigate backtracking
|
|
444
|
+
* because preceding quantifiers can consume the suffix character, forcing
|
|
445
|
+
* the engine to backtrack through them before reaching it.
|
|
446
|
+
*/
|
|
447
|
+
function suffixIsExclusive(node, suffix) {
|
|
448
|
+
if (node.kind === "repetition") {
|
|
449
|
+
// Use getAllLastLeaves to extract actual character-matching tokens
|
|
450
|
+
// from the repetition's child (which may be a group, another
|
|
451
|
+
// repetition, or a leaf token). tokensOverlap alone fails on groups.
|
|
452
|
+
const lastLeaves = getAllLastLeaves(node.child);
|
|
453
|
+
for (const leaf of lastLeaves) {
|
|
454
|
+
if (tokensOverlap(leaf, suffix))
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
return suffixIsExclusive(node.child, suffix);
|
|
458
|
+
}
|
|
459
|
+
if (node.kind === "root" || node.kind === "group") {
|
|
460
|
+
const branches = node.kind === "root" ? node.branches : node.branches;
|
|
461
|
+
for (const branch of branches) {
|
|
462
|
+
for (const child of branch) {
|
|
463
|
+
if (!suffixIsExclusive(child, suffix))
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return true;
|
|
469
|
+
}
|
|
470
|
+
function detectStaticSuffix(root) {
|
|
471
|
+
const suffix = getSuffixToken(root);
|
|
472
|
+
if (!suffix)
|
|
473
|
+
return false;
|
|
474
|
+
return suffixIsExclusive(root, suffix);
|
|
475
|
+
}
|
|
476
|
+
function walkBranches(branches, fn) {
|
|
477
|
+
for (const branch of branches) {
|
|
478
|
+
for (const child of branch) {
|
|
479
|
+
fn(child);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function walkAnalyze(node, state) {
|
|
484
|
+
if (node.kind === "repetition") {
|
|
485
|
+
state.starHeight++;
|
|
486
|
+
if (state.starHeight > state.maxStarHeight) {
|
|
487
|
+
state.maxStarHeight = state.starHeight;
|
|
488
|
+
}
|
|
489
|
+
state.repCount++;
|
|
490
|
+
walkAnalyze(node.child, state);
|
|
491
|
+
state.starHeight--;
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
if (node.kind === "root") {
|
|
495
|
+
walkBranches(node.branches, (child) => walkAnalyze(child, state));
|
|
496
|
+
}
|
|
497
|
+
else if (node.kind === "group") {
|
|
498
|
+
walkBranches(node.branches, (child) => walkAnalyze(child, state));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function walkSafe(node, state) {
|
|
502
|
+
if (node.kind === "repetition") {
|
|
503
|
+
state.starHeight++;
|
|
504
|
+
state.repCount++;
|
|
505
|
+
if (state.starHeight > 1 && !isUnambiguous(node.child))
|
|
506
|
+
return false;
|
|
507
|
+
if (state.repCount > state.limit)
|
|
508
|
+
return false;
|
|
509
|
+
if (findAlternationReDoS(node.child))
|
|
510
|
+
return false;
|
|
511
|
+
const savedHeight = state.starHeight;
|
|
512
|
+
if (isUnambiguous(node.child)) {
|
|
513
|
+
state.starHeight = 0;
|
|
514
|
+
}
|
|
515
|
+
const result = walkSafe(node.child, state);
|
|
516
|
+
if (isUnambiguous(node.child)) {
|
|
517
|
+
state.starHeight = savedHeight;
|
|
518
|
+
}
|
|
519
|
+
state.starHeight--;
|
|
520
|
+
return result;
|
|
521
|
+
}
|
|
522
|
+
if (node.kind === "root") {
|
|
523
|
+
for (const branch of node.branches) {
|
|
524
|
+
for (const child of branch) {
|
|
525
|
+
if (!walkSafe(child, state))
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
else if (node.kind === "group") {
|
|
531
|
+
for (const branch of node.branches) {
|
|
532
|
+
for (const child of branch) {
|
|
533
|
+
if (!walkSafe(child, state))
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// Leaf tokens are inherently safe
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
// ── Severity assessment ───────────────────────────────────────────────────
|
|
542
|
+
function assessSeverity(starHeight, repCount, limit, hasAlternation, hasSeqOverlap, anchored, hasStaticSuffix) {
|
|
543
|
+
if (starHeight >= 3)
|
|
544
|
+
return "critical";
|
|
545
|
+
if (starHeight >= 2 || hasAlternation || hasSeqOverlap) {
|
|
546
|
+
const mitigated = (anchored ? 1 : 0) + (hasStaticSuffix ? 1 : 0);
|
|
547
|
+
return mitigated >= 1 ? "low" : "high";
|
|
548
|
+
}
|
|
549
|
+
if (repCount > limit * 2)
|
|
550
|
+
return "high";
|
|
551
|
+
if (repCount > limit)
|
|
552
|
+
return "low";
|
|
553
|
+
return "none";
|
|
554
|
+
}
|
|
555
|
+
// ── Public API ────────────────────────────────────────────────────────────
|
|
556
|
+
export function analyze(ast, opts = {}) {
|
|
557
|
+
const limit = opts.limit ?? 25;
|
|
558
|
+
const state = {
|
|
559
|
+
starHeight: 0,
|
|
560
|
+
maxStarHeight: 0,
|
|
561
|
+
repCount: 0,
|
|
562
|
+
limit,
|
|
563
|
+
};
|
|
564
|
+
walkAnalyze(ast, state);
|
|
565
|
+
const hasAlt = findAlternationReDoS(ast);
|
|
566
|
+
const hasSeqOverlap = findSequentialOverlap(ast, false);
|
|
567
|
+
const anchored = detectAnchored(ast);
|
|
568
|
+
const hasSuffix = detectStaticSuffix(ast);
|
|
569
|
+
const severity = assessSeverity(state.maxStarHeight, state.repCount, limit, hasAlt, hasSeqOverlap, anchored, hasSuffix);
|
|
570
|
+
const safeState = {
|
|
571
|
+
starHeight: 0,
|
|
572
|
+
maxStarHeight: 0,
|
|
573
|
+
repCount: 0,
|
|
574
|
+
limit,
|
|
575
|
+
};
|
|
576
|
+
const walkSafeResult = walkSafe(ast, safeState);
|
|
577
|
+
const safe = walkSafeResult && !hasSeqOverlap;
|
|
578
|
+
const reasons = [];
|
|
579
|
+
let finalSeverity = "none";
|
|
580
|
+
if (!safe) {
|
|
581
|
+
finalSeverity = severity;
|
|
582
|
+
if (state.maxStarHeight >= 2) {
|
|
583
|
+
reasons.push(`Nested repetition detected (star height ${state.maxStarHeight})`);
|
|
584
|
+
}
|
|
585
|
+
if (hasAlt) {
|
|
586
|
+
reasons.push("Alternatives with overlapping prefixes inside quantifier");
|
|
587
|
+
}
|
|
588
|
+
if (hasSeqOverlap) {
|
|
589
|
+
reasons.push("Sequential overlapping quantifiers: adjacent repetitions whose match domains overlap allowing cascading backtracking");
|
|
590
|
+
}
|
|
591
|
+
if (state.repCount > limit) {
|
|
592
|
+
reasons.push(`Exceeded repetition limit: ${state.repCount} > ${limit}`);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
safe,
|
|
597
|
+
severity: finalSeverity,
|
|
598
|
+
reasons,
|
|
599
|
+
starHeight: state.maxStarHeight,
|
|
600
|
+
repCount: state.repCount,
|
|
601
|
+
hasAlternationReDoS: hasAlt,
|
|
602
|
+
hasSequentialOverlap: hasSeqOverlap,
|
|
603
|
+
anchored,
|
|
604
|
+
hasStaticSuffix: hasSuffix,
|
|
605
|
+
fix: null,
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"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"}
|