/** * @fileoverview Rule to forbid control charactes from regular expressions. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { docs: { description: "disallow control characters in regular expressions", category: "Possible Errors", recommended: true }, schema: [] }, create: function(context) { /** * Get the regex expression * @param {ASTNode} node node to evaluate * @returns {*} Regex if found else null * @private */ function getRegExp(node) { if (node.value instanceof RegExp) { return node.value; } else if (typeof node.value === "string") { var parent = context.getAncestors().pop(); if ((parent.type === "NewExpression" || parent.type === "CallExpression") && parent.callee.type === "Identifier" && parent.callee.name === "RegExp" ) { // there could be an invalid regular expression string try { return new RegExp(node.value); } catch (ex) { return null; } } } return null; } /** * Check if given regex string has control characters in it * @param {String} regexStr regex as string to check * @returns {Boolean} returns true if finds control characters on given string * @private */ function hasControlCharacters(regexStr) { // check control characters, if RegExp object used var hasControlChars = /[\x00-\x1f]/.test(regexStr); // eslint-disable-line no-control-regex // check substr, if regex literal used var subStrIndex = regexStr.search(/\\x[01][0-9a-f]/i); if (!hasControlChars && subStrIndex > -1) { // is it escaped, check backslash count var possibleEscapeCharacters = regexStr.substr(0, subStrIndex).match(/\\+$/gi); hasControlChars = possibleEscapeCharacters === null || !(possibleEscapeCharacters[0].length % 2); } return hasControlChars; } return { Literal: function(node) { var computedValue, regex = getRegExp(node); if (regex) { computedValue = regex.toString(); if (hasControlCharacters(computedValue)) { context.report(node, "Unexpected control character in regular expression."); } } } }; } };