.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-control-regex.js
1 /**
2  * @fileoverview Rule to forbid control characters from regular expressions.
3  * @author Nicholas C. Zakas
4  */
5
6 "use strict";
7
8 const RegExpValidator = require("regexpp").RegExpValidator;
9 const collector = new (class {
10     constructor() {
11         this._source = "";
12         this._controlChars = [];
13         this._validator = new RegExpValidator(this);
14     }
15
16     onPatternEnter() {
17         this._controlChars = [];
18     }
19
20     onCharacter(start, end, cp) {
21         if (cp >= 0x00 &&
22             cp <= 0x1F &&
23             (
24                 this._source.codePointAt(start) === cp ||
25                 this._source.slice(start, end).startsWith("\\x") ||
26                 this._source.slice(start, end).startsWith("\\u")
27             )
28         ) {
29             this._controlChars.push(`\\x${`0${cp.toString(16)}`.slice(-2)}`);
30         }
31     }
32
33     collectControlChars(regexpStr) {
34         try {
35             this._source = regexpStr;
36             this._validator.validatePattern(regexpStr); // Call onCharacter hook
37         } catch {
38
39             // Ignore syntax errors in RegExp.
40         }
41         return this._controlChars;
42     }
43 })();
44
45 //------------------------------------------------------------------------------
46 // Rule Definition
47 //------------------------------------------------------------------------------
48
49 module.exports = {
50     meta: {
51         type: "problem",
52
53         docs: {
54             description: "disallow control characters in regular expressions",
55             category: "Possible Errors",
56             recommended: true,
57             url: "https://eslint.org/docs/rules/no-control-regex"
58         },
59
60         schema: [],
61
62         messages: {
63             unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}."
64         }
65     },
66
67     create(context) {
68
69         /**
70          * Get the regex expression
71          * @param {ASTNode} node node to evaluate
72          * @returns {RegExp|null} Regex if found else null
73          * @private
74          */
75         function getRegExpPattern(node) {
76             if (node.regex) {
77                 return node.regex.pattern;
78             }
79             if (typeof node.value === "string" &&
80                 (node.parent.type === "NewExpression" || node.parent.type === "CallExpression") &&
81                 node.parent.callee.type === "Identifier" &&
82                 node.parent.callee.name === "RegExp" &&
83                 node.parent.arguments[0] === node
84             ) {
85                 return node.value;
86             }
87
88             return null;
89         }
90
91         return {
92             Literal(node) {
93                 const pattern = getRegExpPattern(node);
94
95                 if (pattern) {
96                     const controlCharacters = collector.collectControlChars(pattern);
97
98                     if (controlCharacters.length > 0) {
99                         context.report({
100                             node,
101                             messageId: "unexpected",
102                             data: {
103                                 controlChars: controlCharacters.join(", ")
104                             }
105                         });
106                     }
107                 }
108             }
109         };
110
111     }
112 };