Repository: jshint/jshint
Pull request #3406 (2019-06-09 01:03:10)

[[FIX]] Allow more escapes with RegExp `u` flag

coveralls: 
[![Coverage Status](https://coveralls.io/builds/23880262/badge)](https://coveralls.io/builds/23880262)

Coverage remained the same at 100.0% when pulling **b0b72e42c727216457259ae972902917eb9d3a65 on jugglinmike:regexp-u-more-escapes** into **0a60c9eb55758891f5b544315563044513913232 on jshint:master**.


Patch:
diff --git a/src/lex.js b/src/lex.js
index 897bcabe..87568c4a 100644
--- a/src/lex.js
+++ b/src/lex.js
@@ -1431,6 +1431,18 @@ Lexer.prototype = {
           checks,
           function() { return true; }
         );
+      } else if (char === "0" && reg.decimalDigit.test(this.peek(index + 1))) {
+        this.triggerAsync(
+          "error",
+          {
+            code: "E016",
+            line: this.line,
+            character: this.char,
+            data: [ "Invalid decimal escape sequence" ]
+          },
+          checks,
+          hasUFlag
+        );
       }
 
       index += 1;
@@ -1707,6 +1719,8 @@ Lexer.prototype = {
           return !escapedChars.split("").every(function(escapedChar) {
               return escapedChar === "u" ||
                 escapedChar === "/" ||
+                escapedChar === "0" ||
+                reg.regexpControlEscapes.test(escapedChar) ||
                 reg.regexpCharClasses.test(escapedChar) ||
                 reg.regexpSyntaxChars.test(escapedChar);
             });
diff --git a/src/reg.js b/src/reg.js
index bb1804a4..0595c7cd 100644
--- a/src/reg.js
+++ b/src/reg.js
@@ -49,6 +49,8 @@ exports.regexpSyntaxChars = /[\^$\\.*+?()[\]{}|]/;
 
 exports.regexpQuantifiers = /[*+?{]/;
 
+exports.regexpControlEscapes = /[fnrtv]/;
+
 exports.regexpCharClasses = /[dDsSwW]/;
 
 // Identifies the "dot" atom in regular expressions


Test patch:
diff --git a/tests/unit/parser.js b/tests/unit/parser.js
index 98e6f1c6..603aea75 100644
--- a/tests/unit/parser.js
+++ b/tests/unit/parser.js
@@ -700,6 +700,20 @@ exports.regexp.basic = function (test) {
     .addError(1, 9, "Invalid regular expression.")
     .test("var a = /.*/ii;");
 
+  TestRun(test, "Invalid Decimal Escape Sequence tolerated without `u` flag")
+    .test([
+      "void /\\00/;",
+      "void /\\01/;",
+      "void /\\02/;",
+      "void /\\03/;",
+      "void /\\04/;",
+      "void /\\05/;",
+      "void /\\06/;",
+      "void /\\07/;",
+      "void /\\08/;",
+      "void /\\09/;"
+    ]);
+
   test.done();
 };
 
@@ -816,6 +830,29 @@ exports.regexp.uFlag = function (test) {
   TestRun(test)
     .test('void /[\\s0-1\\s2-3\\s]/u;', { esversion: 6 });
 
+  TestRun(test, "Null CharacterEscape")
+    .test([
+      "void /\\0/u;",
+      "void /\\0a/u;"
+    ], { esversion: 6 });
+
+  TestRun(test)
+    .addError(1, 6, "Invalid regular expression.")
+    .test("void /\\00/u;", { esversion: 6 });
+
+  TestRun(test)
+    .addError(1, 6, "Invalid regular expression.")
+    .test("void /\\01/u;", { esversion: 6 });
+
+  TestRun(test, "ControlEscape")
+    .test([
+      "void /\\f/u;",
+      "void /\\n/u;",
+      "void /\\r/u;",
+      "void /\\t/u;",
+      "void /\\v/u;"
+    ], { esversion: 6 });
+
   test.done();
 };