2 * @fileoverview Validate strings passed to the RegExp constructor
3 * @author Michael Ficarra
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
11 const RegExpValidator = require("regexpp").RegExpValidator;
12 const validator = new RegExpValidator({ ecmaVersion: 2018 });
13 const validFlags = /[gimuys]/gu;
14 const undefined1 = void 0;
16 //------------------------------------------------------------------------------
18 //------------------------------------------------------------------------------
25 description: "disallow invalid regular expression strings in `RegExp` constructors",
26 category: "Possible Errors",
28 url: "https://eslint.org/docs/rules/no-invalid-regexp"
34 allowConstructorFlags: {
41 additionalProperties: false
47 const options = context.options[0];
48 let allowedFlags = null;
50 if (options && options.allowConstructorFlags) {
51 const temp = options.allowConstructorFlags.join("").replace(validFlags, "");
54 allowedFlags = new RegExp(`[${temp}]`, "giu");
59 * Check if node is a string
60 * @param {ASTNode} node node to evaluate
61 * @returns {boolean} True if its a string
64 function isString(node) {
65 return node && node.type === "Literal" && typeof node.value === "string";
69 * Check syntax error in a given pattern.
70 * @param {string} pattern The RegExp pattern to validate.
71 * @param {boolean} uFlag The Unicode flag.
72 * @returns {string|null} The syntax error.
74 function validateRegExpPattern(pattern, uFlag) {
76 validator.validatePattern(pattern, undefined1, undefined1, uFlag);
84 * Check syntax error in a given flags.
85 * @param {string} flags The RegExp flags to validate.
86 * @returns {string|null} The syntax error.
88 function validateRegExpFlags(flags) {
90 validator.validateFlags(flags);
93 return `Invalid flags supplied to RegExp constructor '${flags}'`;
98 "CallExpression, NewExpression"(node) {
99 if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp" || !isString(node.arguments[0])) {
102 const pattern = node.arguments[0].value;
103 let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
106 flags = flags.replace(allowedFlags, "");
109 // If flags are unknown, check both are errored or not.
110 const message = validateRegExpFlags(flags) || (
112 ? validateRegExpPattern(pattern, flags.indexOf("u") !== -1)
113 : validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
119 message: "{{message}}.",