UNPKG

3.19 kBJavaScriptView Raw
1/**
2 * @fileoverview Validate strings passed to the RegExp constructor
3 * @author Michael Ficarra
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Requirements
9//------------------------------------------------------------------------------
10
11const espree = require("espree");
12
13//------------------------------------------------------------------------------
14// Rule Definition
15//------------------------------------------------------------------------------
16
17module.exports = {
18 meta: {
19 docs: {
20 description: "disallow invalid regular expression strings in `RegExp` constructors",
21 category: "Possible Errors",
22 recommended: true,
23 url: "https://eslint.org/docs/rules/no-invalid-regexp"
24 },
25
26 schema: [{
27 type: "object",
28 properties: {
29 allowConstructorFlags: {
30 type: "array",
31 items: {
32 type: "string"
33 }
34 }
35 },
36 additionalProperties: false
37 }]
38 },
39
40 create(context) {
41
42 const options = context.options[0];
43 let allowedFlags = "";
44
45 if (options && options.allowConstructorFlags) {
46 allowedFlags = options.allowConstructorFlags.join("");
47 }
48
49 /**
50 * Check if node is a string
51 * @param {ASTNode} node node to evaluate
52 * @returns {boolean} True if its a string
53 * @private
54 */
55 function isString(node) {
56 return node && node.type === "Literal" && typeof node.value === "string";
57 }
58
59 /**
60 * Validate strings passed to the RegExp constructor
61 * @param {ASTNode} node node to evaluate
62 * @returns {void}
63 * @private
64 */
65 function check(node) {
66 if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0])) {
67 let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
68
69 if (allowedFlags) {
70 flags = flags.replace(new RegExp(`[${allowedFlags}]`, "gi"), "");
71 }
72
73 try {
74 void new RegExp(node.arguments[0].value);
75 } catch (e) {
76 context.report({
77 node,
78 message: "{{message}}.",
79 data: e
80 });
81 }
82
83 if (flags) {
84
85 try {
86 espree.parse(`/./${flags}`, context.parserOptions);
87 } catch (ex) {
88 context.report({
89 node,
90 message: "Invalid flags supplied to RegExp constructor '{{flags}}'.",
91 data: {
92 flags
93 }
94 });
95 }
96 }
97
98 }
99 }
100
101 return {
102 CallExpression: check,
103 NewExpression: check
104 };
105
106 }
107};