]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Validate strings passed to the RegExp constructor | |
3 | * @author Michael Ficarra | |
4 | */ | |
5 | ||
6 | "use strict"; | |
7 | ||
8 | //------------------------------------------------------------------------------ | |
9 | // Requirements | |
10 | //------------------------------------------------------------------------------ | |
11 | ||
12 | const rule = require("../../../lib/rules/no-invalid-regexp"), | |
13 | { RuleTester } = require("../../../lib/rule-tester"); | |
14 | ||
15 | const ruleTester = new RuleTester(); | |
16 | ||
17 | ruleTester.run("no-invalid-regexp", rule, { | |
18 | valid: [ | |
19 | "RegExp('')", | |
20 | "RegExp()", | |
21 | "RegExp('.', 'g')", | |
22 | "new RegExp('.')", | |
23 | "new RegExp", | |
24 | "new RegExp('.', 'im')", | |
25 | "global.RegExp('\\\\')", | |
26 | "new RegExp('.', y)", | |
456be15e TL |
27 | "new RegExp('.', 'y')", |
28 | "new RegExp('.', 'u')", | |
29 | "new RegExp('.', 'yu')", | |
30 | "new RegExp('/', 'yu')", | |
31 | "new RegExp('\\/', 'yu')", | |
32 | "new RegExp('\\\\u{65}', 'u')", | |
33 | "new RegExp('\\\\u{65}*', 'u')", | |
34 | "new RegExp('[\\\\u{0}-\\\\u{1F}]', 'u')", | |
35 | "new RegExp('.', 's')", | |
36 | "new RegExp('(?<=a)b')", | |
37 | "new RegExp('(?<!a)b')", | |
38 | "new RegExp('(?<a>b)\\k<a>')", | |
39 | "new RegExp('(?<a>b)\\k<a>', 'u')", | |
40 | "new RegExp('\\\\p{Letter}', 'u')", | |
41 | ||
5422a9cc TL |
42 | // unknown flags |
43 | "RegExp('{', flags)", // valid without the "u" flag | |
44 | "new RegExp('{', flags)", // valid without the "u" flag | |
45 | "RegExp('\\\\u{0}*', flags)", // valid with the "u" flag | |
46 | "new RegExp('\\\\u{0}*', flags)", // valid with the "u" flag | |
47 | { | |
48 | code: "RegExp('{', flags)", // valid without the "u" flag | |
49 | options: [{ allowConstructorFlags: ["u"] }] | |
50 | }, | |
51 | { | |
52 | code: "RegExp('\\\\u{0}*', flags)", // valid with the "u" flag | |
53 | options: [{ allowConstructorFlags: ["a"] }] | |
54 | }, | |
55 | ||
456be15e TL |
56 | // ES2020 |
57 | "new RegExp('(?<\\\\ud835\\\\udc9c>.)', 'g')", | |
58 | "new RegExp('(?<\\\\u{1d49c}>.)', 'g')", | |
59 | "new RegExp('(?<𝒜>.)', 'g');", | |
60 | "new RegExp('\\\\p{Script=Nandinagari}', 'u');", | |
61 | ||
62 | // allowConstructorFlags | |
63 | { | |
64 | code: "new RegExp('.', 'g')", | |
65 | options: [{ allowConstructorFlags: [] }] | |
66 | }, | |
67 | { | |
68 | code: "new RegExp('.', 'g')", | |
69 | options: [{ allowConstructorFlags: ["a"] }] | |
70 | }, | |
71 | { | |
72 | code: "new RegExp('.', 'a')", | |
73 | options: [{ allowConstructorFlags: ["a"] }] | |
74 | }, | |
75 | { | |
76 | code: "new RegExp('.', 'ag')", | |
77 | options: [{ allowConstructorFlags: ["a"] }] | |
78 | }, | |
79 | { | |
80 | code: "new RegExp('.', 'ga')", | |
81 | options: [{ allowConstructorFlags: ["a"] }] | |
82 | }, | |
83 | { | |
84 | code: "new RegExp('.', 'a')", | |
85 | options: [{ allowConstructorFlags: ["a", "z"] }] | |
86 | }, | |
87 | { | |
88 | code: "new RegExp('.', 'z')", | |
89 | options: [{ allowConstructorFlags: ["a", "z"] }] | |
90 | }, | |
91 | { | |
92 | code: "new RegExp('.', 'az')", | |
93 | options: [{ allowConstructorFlags: ["a", "z"] }] | |
94 | }, | |
95 | { | |
96 | code: "new RegExp('.', 'za')", | |
97 | options: [{ allowConstructorFlags: ["a", "z"] }] | |
98 | }, | |
99 | { | |
100 | code: "new RegExp('.', 'agz')", | |
101 | options: [{ allowConstructorFlags: ["a", "z"] }] | |
102 | } | |
eb39fafa DC |
103 | ], |
104 | invalid: [ | |
105 | { | |
106 | code: "RegExp('[');", | |
107 | errors: [{ | |
108 | messageId: "regexMessage", | |
109 | data: { message: "Invalid regular expression: /[/: Unterminated character class" }, | |
110 | type: "CallExpression" | |
111 | }] | |
112 | }, | |
113 | { | |
114 | code: "RegExp('.', 'z');", | |
115 | errors: [{ | |
116 | messageId: "regexMessage", | |
117 | data: { message: "Invalid flags supplied to RegExp constructor 'z'" }, | |
118 | type: "CallExpression" | |
119 | }] | |
120 | }, | |
456be15e TL |
121 | { |
122 | code: "RegExp('.', 'a');", | |
123 | options: [{}], | |
124 | errors: [{ | |
125 | messageId: "regexMessage", | |
126 | data: { message: "Invalid flags supplied to RegExp constructor 'a'" }, | |
127 | type: "CallExpression" | |
128 | }] | |
129 | }, | |
130 | { | |
131 | code: "new RegExp('.', 'a');", | |
132 | options: [{ allowConstructorFlags: [] }], | |
133 | errors: [{ | |
134 | messageId: "regexMessage", | |
135 | data: { message: "Invalid flags supplied to RegExp constructor 'a'" }, | |
136 | type: "NewExpression" | |
137 | }] | |
138 | }, | |
139 | { | |
140 | code: "new RegExp('.', 'z');", | |
141 | options: [{ allowConstructorFlags: ["a"] }], | |
142 | errors: [{ | |
143 | messageId: "regexMessage", | |
144 | data: { message: "Invalid flags supplied to RegExp constructor 'z'" }, | |
145 | type: "NewExpression" | |
146 | }] | |
147 | }, | |
148 | { | |
149 | code: "new RegExp('.', 'az');", | |
150 | options: [{ allowConstructorFlags: ["z"] }], | |
151 | errors: [{ | |
152 | messageId: "regexMessage", | |
153 | data: { message: "Invalid flags supplied to RegExp constructor 'a'" }, | |
154 | type: "NewExpression" | |
155 | }] | |
156 | }, | |
eb39fafa DC |
157 | { |
158 | code: "new RegExp(')');", | |
159 | errors: [{ | |
160 | messageId: "regexMessage", | |
161 | data: { message: "Invalid regular expression: /)/: Unmatched ')'" }, | |
162 | type: "NewExpression" | |
163 | }] | |
164 | }, | |
456be15e TL |
165 | { |
166 | code: String.raw`new RegExp('\\a', 'u');`, | |
167 | errors: [{ | |
168 | messageId: "regexMessage", | |
169 | data: { message: "Invalid regular expression: /\\a/u: Invalid escape" }, | |
170 | type: "NewExpression" | |
171 | }] | |
172 | }, | |
173 | { | |
174 | code: String.raw`new RegExp('\\a', 'u');`, | |
175 | options: [{ allowConstructorFlags: ["u"] }], | |
176 | errors: [{ | |
177 | messageId: "regexMessage", | |
178 | data: { message: "Invalid regular expression: /\\a/u: Invalid escape" }, | |
179 | type: "NewExpression" | |
180 | }] | |
181 | }, | |
5422a9cc TL |
182 | { |
183 | code: String.raw`RegExp('\\u{0}*');`, | |
184 | errors: [{ | |
185 | messageId: "regexMessage", | |
186 | data: { message: "Invalid regular expression: /\\u{0}*/: Nothing to repeat" }, | |
187 | type: "CallExpression" | |
188 | }] | |
189 | }, | |
190 | { | |
191 | code: String.raw`new RegExp('\\u{0}*');`, | |
192 | errors: [{ | |
193 | messageId: "regexMessage", | |
194 | data: { message: "Invalid regular expression: /\\u{0}*/: Nothing to repeat" }, | |
195 | type: "NewExpression" | |
196 | }] | |
197 | }, | |
198 | { | |
199 | code: String.raw`new RegExp('\\u{0}*', '');`, | |
200 | errors: [{ | |
201 | messageId: "regexMessage", | |
202 | data: { message: "Invalid regular expression: /\\u{0}*/: Nothing to repeat" }, | |
203 | type: "NewExpression" | |
204 | }] | |
205 | }, | |
206 | { | |
207 | code: String.raw`new RegExp('\\u{0}*', 'a');`, | |
208 | options: [{ allowConstructorFlags: ["a"] }], | |
209 | errors: [{ | |
210 | messageId: "regexMessage", | |
211 | data: { message: "Invalid regular expression: /\\u{0}*/: Nothing to repeat" }, | |
212 | type: "NewExpression" | |
213 | }] | |
214 | }, | |
215 | { | |
216 | code: String.raw`RegExp('\\u{0}*');`, | |
217 | options: [{ allowConstructorFlags: ["a"] }], | |
218 | errors: [{ | |
219 | messageId: "regexMessage", | |
220 | data: { message: "Invalid regular expression: /\\u{0}*/: Nothing to repeat" }, | |
221 | type: "CallExpression" | |
222 | }] | |
223 | }, | |
eb39fafa DC |
224 | |
225 | // https://github.com/eslint/eslint/issues/10861 | |
226 | { | |
227 | code: String.raw`new RegExp('\\');`, | |
228 | errors: [{ | |
229 | messageId: "regexMessage", | |
230 | data: { message: "Invalid regular expression: /\\/: \\ at end of pattern" }, | |
231 | type: "NewExpression" | |
232 | }] | |
233 | } | |
234 | ] | |
235 | }); |