redos-detector 0.2.0

static ReDoS vulnerability analysis of ECMA-262 regex patterns
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
// Generated from the canonical behavior table. Do not edit by hand.
mod trail_counts;
pub use trail_counts::TRAIL_COUNTS;

pub enum Exp {
    Safe,
    Unsafe,
    Score(u64),
}

pub struct Case {
    pub source: &'static str,
    pub flags: &'static str,
    pub expected: Exp,
    pub missing_anchor: bool,
    pub infinite: bool,
}

pub const CASES: &[Case] = &[
    Case { source: "^()", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^z(ab){1,2}abab{0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^z(ab){1,2}abab(ab){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[ab]{0,2}a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([^\\\\wb]){0,2}[\\\\wa]?a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([^\\\\db]){0,2}[\\\\d]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^([^\\\\db]){0,2}[\\\\d]?a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a*ba*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*b?a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([^\\\\w]){0,2}[a]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(.b.b){1,2}.(.a){0,4}a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abab){0,3}a(ba){0,1}baa$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc?){0,2}(abab){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,3}b){1,2}(ab){1,4}a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[ab]?[ab]x*b?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[ab]*[ac]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)*(ab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)*a(ba){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)+(a+b)+f$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a*)*", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*a*", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a*)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)*((a+b)+[ax]b)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)*((a+b)[ax]b)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)*(a+c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}b)*(a{1,2}c){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}b?)*(a{1,2}c){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}b)*(a{1,2}b){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}b)*(ab){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{0,1}b)*(a{0,2}b){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{0,1}b)*(a{1,2}b){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}b)*(a{1,2}b){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}b)*(a{1,2}b){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,3}b)*(a{1,2}b){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,3})*(a{1,2}){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a*(a{1,2}){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2})*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2})*(a{1,2}c){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2})+(ac){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)*((ab)+c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[ab]*ab*c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[ab]*cb*c$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b){0,10}(a+b){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[ab]*(ab)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)+(a+b)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)+(a+c)+f$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(aa)*(aaa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(aa)*a?(aaa)?", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(){2,3}aa?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([^bc]){0,2}b?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(aaaa){0,2}(a){0,10}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a{0,2}(aa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a{0,2}(aaa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab){0,2}(ab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab){0,2}(abab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab){0,2}(ababab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab){0,2}a(ba)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab){0,2}a(baba)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab){0,2}a(bababa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc?){0,2}a(bababa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b){0,2}a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b){0,2}(a|b)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b){0,2}c?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(){0,2}c?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^()*c?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^()*c?()*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*()*b*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*()*a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b*)b+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[^]+a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\d+[0-9]*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[^\\d]+[0-9]*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\D+[0-9]*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[\\D\\d]+[0-9]*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\D1]+[0-9]*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\D+\\d*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[^\\w]+a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\w+a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\w]+a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\w]+[^\\w]a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[\\w]+(b|[^\\w])a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([\\w]|[^\\w])+a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([a]|[^a])+b*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([a]|[^a])+ab*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([a]|[^a])+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^([a-d]|[b-f])+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([a-d]|[b-f])+c*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(|a){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b?){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([a-d]|)+e*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(|[a-d])+e*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|(b|))+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((?=b)|a){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a(?=b)|a){0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|c)*d*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b*|c)b(a|b+|c)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b*|c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b*)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b*)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b+|c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b{1,3}|c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+a{0,3}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|c)+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a|bc*)+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a)+b(\\1)+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a)b(\\1)?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(z)ba?\\1a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(z?)ba?\\1a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)+b\\1+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a)+a(\\1)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)+(\\1)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+a+)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a?)b\\1a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^((a?)b\\2a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^((a?)\\2)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)a\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)b\\1a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)b\\1?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^((a{1,2})\\1)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^((a+)\\1)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^((a+)a+)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+\\99$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)b\\1$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)b\\1+a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)b\\1+a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)b\\1+a{1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)b\\1+a{0,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)b\\1+a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)b\\1+a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)b\\1+a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)\\1$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)\\1+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)\\1+\\1+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)(b+)\\1\\2$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)(b+\\1)\\1\\2$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2})(b{1,2}\\1)\\1\\2$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)(b+\\1)\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)(b*\\1)\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)(b+)\\1\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)(b*)\\1\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:a)(b)a\\1+b+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+)\\1a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a{0,2})\\2a{0,2})$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a{0,2})\\2a{0,2})\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)\\2)\\1b?b?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)b\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a){0}b\\1?a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a){1}b\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a){0,1}b\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)){0}b\\2?a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a){0,1}b\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a){0,1}bc?\\1c?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a){1}bc?\\1c?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a){0}bc?\\1c?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a)|\\1?a?)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:b|(a)b\\1?a?$)", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a)|(c|\\1?a?)$)", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a)|(c|\\1?a?)$)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:c|d|((a)b\\2?a?)$)", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:c|d|((a)b\\2?a?){0}$)", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(c|d|(a)b\\2?a?){0}$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(c|d|(a)b\\2?a?){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)|b)cd?\\2d?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)|b)c\\2?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a){1,2}b\\2\\2)*a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)b\\2b\\2b)*(ab){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)?\\2b)*a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a)\\2b)*(aab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)(\\1a|\\1b)*(aa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)(\\1a|\\1b)*(a\\1)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:a(b)|c\\1?b?)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?:a(b)|c?\\1c?)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(b)?c?\\1c?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a\\1?a)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?\\1a?)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(b)(a?\\1a?)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*ab(cabcab)?c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*ab(cacab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*ab(cabca)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*ab(cabcab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cabca)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cabcab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cabcab)?c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(bcabcab){1,2}", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc)*a(bcabcabca){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(bcabca){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?bc)*(abca){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?bc)*(bca){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?bc)*(bc){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(bca){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(ca){0,1}c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cab){0,1}c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*ab(cab){0,1}c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*ab(ca){0,1}c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc)*a(bca){0,1}bc$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc)*a(bc){0,1}abc$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(bcabcab){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cabcab){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cabca){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab?c)*a(cabcab?){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc)*a(bcabcab){0,1}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|a)", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a|a)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(.|a)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab|a.)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(|a)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a{0}|a)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?|a)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab|a)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|ab)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ac|ab)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(|)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(()|())$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?|b?)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^([a-c]|[d-f])$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^([a-c]|[c-f])$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(aa|a{2})$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab|a(b|c))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a(b|x)c)?ab(ca(b|x))?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[a]?[^b]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[^a]?[^b]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(a))\\1+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(b))\\1a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(b)?)\\1a+v", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a+(?=a+))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a+(?=a+)a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a+(?=a+)a+)a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a+(?=a+$)a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a+(?=a+$)a+b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a+(?=a+)a+$)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(a))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(a))\\1+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(a{0}))\\1+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(b))a+\\1a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(b)?)a+\\1a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=a+a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=a+a+b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=a+a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=a+a+b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(b)(?=a+\\1a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(b))a+\\1a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(b)?)a+\\1a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a?(?=a?)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=b{1,2})b$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(b)(?=b{1,2})\\1$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(aa){1,2}(a\\2){1,2})$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(aa){1,2}(a\\2){1,2}b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a){1,2}(a\\2){1,2})$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a){1,2}(a\\2){1,2}b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=((?=(b+\\1+))))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(b(?=(b+\\1+))))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(b)(?=(b+\\1+)))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(b)(?=(b+\\1+b)))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(b)(?=(b+\\1{2,})))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a(?=(b+\\1b+))))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a(?=(b+\\1b+c))))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=((?=(b+\\1b+))))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=((?=(b+\\1b+c))))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(b)(?=(b+\\1+)))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(b)(?=(b+\\1+c)))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?!a+a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?!a+a+b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?<=a+a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?<=a+a+b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(b)(?<=a+\\1a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?<=a+\\1a+)(b)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?<=a+\\1a+b)(b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?<=(b))a+\\1a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?<=(b)?)a+\\1a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?<=(a))(a\\1)?(aa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?<!a+a+)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?<!a+a+b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?<=a+)a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a+\\b)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+\\B)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:a|a\\B|a\\b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(^a\\b\\B$)+.{10}$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)?(ab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)?a?b?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(abc)?a?b?c?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)?a+b+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)?a*b*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(ab)?(a*|z)b*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((aa)*b)*(a?(a|b))*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a(aa)*b)*aa((a|b)baa)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[a-\\d]+-+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(([01][0-9]|[012][0-3]):([0-5][0-9]))$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(([01][0-9]|[2][0-3]):([0-5][0-9]))$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^([\\d\\w][-\\d\\w]{0,253}[\\d\\w]\\.)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^([^\\x00]{0,220}\\x00)*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^([^\\x00]{0,2}\\x00)*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b)*[^c].*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab)*c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab){0,4}c$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a|b|ab)c?)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a|b|ab)c?){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a|ab)b?)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|ab)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|a)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((a|ab)b?c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|c|ab|bc)*a.*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab|)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|ab|){0,4}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a*b|a*c)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a*b|a*b)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|aabb){0,4}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|aabb)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|b|abab)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(aa|bb|aabb)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(bb|aa|aabb)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(bb|aa|aabbz|z)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}|aa)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^👍+👍+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(👍)+(👍)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^👍+\\udc4d+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^👍+👍+$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\u{1f44d}+\\u{1f44d}+$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\u{1f44d}+\\u{1f44d}+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+\\u{61}+$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\p{L}+a+$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\p{L}+\\P{Number}a+$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\p{L}]+a+$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a{0,9007199254740991}a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a{0,-1}a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(abab)?(ababab)?(ab)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((?::a+)?)(a*)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((?:a+:)?)(a*)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^^a?a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((?:a+:)?)([^b]*)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((?:a+:)?)([^b:]*)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^b?(bc)?c?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^b?c?(bc)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(bc)?b?c?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:b?c?|(bc)?)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(aaa)?a{4,5}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a$a+a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a($|)a+a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a($|)a+a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+a+^a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+a+(^|)a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{252,253}){1,}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{252,253}){1,2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{2,3}){1,}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((aa)|(aaa)){1,3}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^((aa)|(aaa)){1,}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1000,}b)+(a{999,}c)+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{1,2}a{1,2})*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(?:c|(a))){2}ac\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(?:c|(a))){2}ca\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a)?b){2}abb\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a)?b){2}bab\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a)?){2}b\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a*)b\\1?(aaaa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a{4})b\\1?(aaaa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(aa{3})b\\1?(aaaa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(){2}a?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a?){2}x\\1)?(axa)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a?){2}x\\1)?(ax)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:(a?){2}x\\1)?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?:a?(a?)x\\1)?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a?){2}$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b\\1)$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(xx)?(xx||)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(^)*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^($)*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+a+(^)+a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+a+(^)*a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a)^a+a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^($)+a+a+$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^($)*a+a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^b(a)?^\\1?a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^b(a)?^(a\\1)(aa)?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a)?^\\1?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a?)b)\\1a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^.?[a-z]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^.?[^a-z]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)(\\1)(\\2)x\\3?(a)?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a(?!(a))\\1$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?!(b(?=(c))))xc?\\2?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a?)a?x\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)?(a+c)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a+b)?(a+c)$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^^(?=((?=(a*))\\2.*))\\1a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a(?=b+))+^\\1?a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a(?!b+))+^\\1?a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a(?<=b+))+^\\1?a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a(?<!b+))+^\\1?a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a?a?)", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=a?a?$)", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)(\\1)\\2?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a)(\\1)(\\2)\\3?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^($)\\1", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(a)\\1?\\1?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(^a)\\1?\\1?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*a*", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*a+", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a+a+", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a?a?(?=(a){0})$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(a|a|a|a)", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a.*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a.{0,1}b$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a.{0,2}b$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a.{0,}b$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a{0,1}))\\1a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a?))\\1a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a?b))\\1a?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a(?=(a{0,1}))\\1$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a?(?=(a{0,1}))\\1$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a?a?))\\1a$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a+(?=(a))\\1a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a*(?=(a))\\1a+$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a*(?=(a?))\\1a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a*(?=(b))\\1a*$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a*(?=(b?))\\1a*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a{0,1})b)\\1a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^(?=(a{0,1})b)\\1a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[a-z]?[A-Z]?$", flags: "i", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a?A?$", flags: "i", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[E-c]?d?$", flags: "i", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[E-c]?e?$", flags: "i", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[^a]?A?$", flags: "i", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^.?[\\r\\n\\u2028-\\u2029].?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^.?[\\r\\n\\u2028-\\u2029].?$", flags: "s", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^.?a?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^.?[\\n\\r\\u2028\\u2029]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^.?[\\n\\r\\u2028\\u2029]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\d?[^0-9]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\d?[0-9]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\D?[0-9]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\D?[^0-9]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\w?[^A-Za-z0-9_]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\w?[A-Za-z0-9_]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\W?[A-Za-z0-9_]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\W?[^A-Za-z0-9_]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\s?[^\\f\\n\\r\\t\\v\\u0020\\u00a0\\u1680\\u2000-\\u200a\\u2028-\\u2029\\u202f\\u205f\\u3000\\ufeff]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\s?[\\f\\n\\r\\t\\v\\u0020\\u00a0\\u1680\\u2000-\\u200a\\u2028-\\u2029\\u202f\\u205f\\u3000\\ufeff]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\S?[\\f\\n\\r\\t\\v\\u0020\\u00a0\\u1680\\u2000-\\u200a\\u2028-\\u2029\\u202f\\u205f\\u3000\\ufeff]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\S?[^\\f\\n\\r\\t\\v\\u0020\\u00a0\\u1680\\u2000-\\u200a\\u2028-\\u2029\\u202f\\u205f\\u3000\\ufeff]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^.?[\\n\\r\\u2028-\\u2029]?$", flags: "", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^.?[^\\n\\r\\u2028-\\u2029]?$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a?a?[\\n\\r\\u2028-\\u2029]{2}", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^a?a?[\\n\\r\\u2028-\\u2029]{2}", flags: "m", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^a?a?[\\n\\r\\u2028-\\u2029]{2}$", flags: "m", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\p{Lowercase_Letter}?\\p{Lowercase_Letter}?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\P{Lowercase_Letter}?\\P{Lowercase_Letter}?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\p{Lowercase_Letter}?\\P{Lowercase_Letter}?$", flags: "u", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\P{Lowercase_Letter}?\\p{Lowercase_Letter}?$", flags: "u", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^\\P{Lowercase_Letter}?\\p{Lowercase_Letter}?a?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\p{Lowercase_Letter}]?[\\p{Lowercase_Letter}]?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\P{Lowercase_Letter}]?[\\P{Lowercase_Letter}]?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\p{Lowercase_Letter}]?[\\P{Lowercase_Letter}]?$", flags: "u", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[\\P{Lowercase_Letter}]?[\\p{Lowercase_Letter}]?$", flags: "u", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[\\p{Lowercase_Letter}]?[^\\p{Lowercase_Letter}]?$", flags: "u", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[\\P{Lowercase_Letter}]?[^\\P{Lowercase_Letter}]?$", flags: "u", expected: Exp::Safe, missing_anchor: false, infinite: false },
    Case { source: "^[\\p{Lowercase_Letter}]?[\\P{Lowercase_Letter}\\p{Lowercase_Letter}]?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^[\\p{Lowercase_Letter}]?[\\p{Lowercase_Letter}\\P{Lowercase_Letter}]?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "^\\P{Lowercase_Letter}?a?$", flags: "u", expected: Exp::Unsafe, missing_anchor: false, infinite: false },
    Case { source: "a", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "a*a*", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "(a|a)", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "(?=a+a+)$", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "(?=a+a+$)$", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "ab", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "a*a+", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "a*a{2,}", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "a*aa", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "(a+)+", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "(a+)+$", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "(a+)+a", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "(a|aa)", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "^(a{0,3}bc)x\\1*(aaabc)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: true },
    Case { source: "^((a{0,3})bc)x\\1*(aaabc)*$", flags: "", expected: Exp::Unsafe, missing_anchor: false, infinite: true },
    Case { source: "\\s+", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "(a+)+", flags: "", expected: Exp::Safe, missing_anchor: true, infinite: false },
    Case { source: "(a+)+$", flags: "", expected: Exp::Unsafe, missing_anchor: true, infinite: false },
    Case { source: "^(?:-(?:[a-z][a-z\\d]{4,7}|\\d[a-z\\d]{3,7}))*(?:_[^x](?:_[a-z\\d]{2}(_[a-z\\d]{3,8})*)+)?$", flags: "", expected: Exp::Score(2), missing_anchor: false, infinite: false },
    Case { source: "^(?:-(?:[a-z][a-z\\d]{4,7}|\\d[a-z\\d]{3,7}))*(?:_[^x](?:_[a-z\\d]{2}(_[a-z\\d]{3,8}){0,5})+)?$", flags: "", expected: Exp::Score(2), missing_anchor: false, infinite: false },
    Case { source: "^(?:-(?:[a-z][a-z\\d]{4,7}|\\d[a-z\\d]{3,7}))*(?:_[^x](?:_[a-z\\d]{2}(_[a-z\\d]{3,8}){0,2})+)?$", flags: "", expected: Exp::Score(2), missing_anchor: false, infinite: false },
    Case { source: "^(?:-(?:[a-z][a-z\\d]{4,7}|\\d[a-z\\d]{3,7}))*(?:_[^x](?:_[a-z\\d]{2}(_[a-z\\d]{3,8}){0,2}){1,5})?$", flags: "", expected: Exp::Score(2), missing_anchor: false, infinite: false },
];