Skip to content

Commit

Permalink
Update: improve error message in no-control-regex (fixes #6293)
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Aug 4, 2016
1 parent 579ec49 commit e8b7bd2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
41 changes: 31 additions & 10 deletions lib/rules/no-control-regex.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,42 @@ module.exports = {
return null;
}


const controlChar = /[\x00-\x1f]/g; // eslint-disable-line no-control-regex
const doubleSlashes = /\\\\/g;
const multipleSlashes = /\\+$/g;

/**
* Check if given regex string has control characters in it
* Return a list of the control characters in the given regex string
* @param {string} regexStr regex as string to check
* @returns {boolean} returns true if finds control characters on given string
* @returns {array} returns a list of found control characters on given string
* @private
*/
function hasControlCharacters(regexStr) {
function getControlCharacters(regexStr) {

// check control characters, if RegExp object used
let hasControlChars = /[\x00-\x1f]/.test(regexStr); // eslint-disable-line no-control-regex
const controlChars = regexStr.match(controlChar) || [];

let stringControlChars = [];

// check substr, if regex literal used
const subStrIndex = regexStr.search(/\\x[01][0-9a-f]/i);

if (!hasControlChars && subStrIndex > -1) {
if (subStrIndex > -1) {

// is it escaped, check backslash count
const possibleEscapeCharacters = regexStr.substr(0, subStrIndex).match(/\\+$/gi);
const possibleEscapeCharacters = regexStr.slice(0, subStrIndex).match(multipleSlashes);

hasControlChars = possibleEscapeCharacters === null || !(possibleEscapeCharacters[0].length % 2);
const hasControlChars = possibleEscapeCharacters === null || !(possibleEscapeCharacters[0].length % 2);

if (hasControlChars) {
stringControlChars = regexStr.slice(subStrIndex, -1).replace(doubleSlashes, ",\\").split(",");
}
}

return hasControlChars;
return controlChars.map(function(x) {
return "\\x" + ("00" + x.charCodeAt(0).toString(16)).slice(-2);
}).concat(stringControlChars);
}

return {
Expand All @@ -83,8 +96,16 @@ module.exports = {
if (regex) {
const computedValue = regex.toString();

if (hasControlCharacters(computedValue)) {
context.report(node, "Unexpected control character in regular expression.");
const controlCharacters = getControlCharacters(computedValue);

if (controlCharacters.length > 0) {
context.report({
node,
message: "Unexpected control character(s) in regular expression: {{controlChars}}.",
data: {
controlChars: controlCharacters.join(", ")
}
});
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions tests/lib/rules/no-control-regex.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ ruleTester.run("no-control-regex", rule, {
"new (function foo(){})('\\x1f')"
],
invalid: [
{ code: "var regex = " + /\x1f/, errors: [{ message: "Unexpected control character in regular expression.", type: "Literal"}] }, // eslint-disable-line no-control-regex
{ code: "var regex = " + /\\\x1f/, errors: [{ message: "Unexpected control character in regular expression.", type: "Literal"}] }, // eslint-disable-line no-control-regex
{ code: "var regex = new RegExp('\\x1f')", errors: [{ message: "Unexpected control character in regular expression.", type: "Literal"}] },
{ code: "var regex = RegExp('\\x1f')", errors: [{ message: "Unexpected control character in regular expression.", type: "Literal"}] }
{ code: "var regex = " + /\x1f/, errors: [{ message: "Unexpected control character(s) in regular expression: \\x1f.", type: "Literal"}] }, // eslint-disable-line no-control-regex
{ code: "var regex = " + /\\\x1f\\x1e/, errors: [{ message: "Unexpected control character(s) in regular expression: \\x1f, \\x1e.", type: "Literal"}] }, // eslint-disable-line no-control-regex
{ code: "var regex = new RegExp('\\x1f\\x1e')", errors: [{ message: "Unexpected control character(s) in regular expression: \\x1f, \\x1e.", type: "Literal"}] },
{ code: "var regex = RegExp('\\x1f')", errors: [{ message: "Unexpected control character(s) in regular expression: \\x1f.", type: "Literal"}] }
]
});

0 comments on commit e8b7bd2

Please sign in to comment.