Move OctalEscapeSequence to read_escape_char
authorAnthony Van de Gejuchte <anthonyvdgent@gmail.com>
Thu, 23 Jun 2016 14:53:48 +0000 (16:53 +0200)
committerRichard van Velzen <rvanvelzen1@gmail.com>
Thu, 30 Jun 2016 19:42:15 +0000 (21:42 +0200)
This should simplify and improve implementation, make it easier to
implement template strings, and keep master a bit more in sync with
harmony.

Previous implementation wasn't broken, though the loop gave me the
impression it could read infinite numbers and annoyed me a bit. It was
also slightly unnecessary because the lookup involved only 3 characters.

lib/parse.js
test/compress/string-literal.js [new file with mode: 0644]
test/mocha/string-literal.js

index a573234..c7089b2 100644 (file)
@@ -365,7 +365,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
           case 98  : return "\b";
           case 118 : return "\u000b"; // \v
           case 102 : return "\f";
-          case 48  : return "\0";
           case 120 : return String.fromCharCode(hex_bytes(2)); // \x
           case 117 : return String.fromCharCode(hex_bytes(4)); // \u
           case 10  : return ""; // newline
@@ -375,9 +374,27 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
                 return "";
             }
         }
+        if (ch >= "0" && ch <= "7")
+            return read_octal_escape_sequence(ch);
         return ch;
     };
 
+    function read_octal_escape_sequence(ch) {
+        // Read
+        var p = peek();
+        if (p >= "0" && p <= "7") {
+            ch += next(true);
+            if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
+                ch += next(true);
+        }
+
+        // Parse
+        if (ch === "0") return "\0";
+        if (ch.length > 0 && next_token.has_directive("use strict"))
+            parse_error("SyntaxError: Octal literals are not allowed in strict mode");
+        return String.fromCharCode(parseInt(ch, 8));
+    }
+
     function hex_bytes(n) {
         var num = 0;
         for (; n > 0; --n) {
@@ -393,27 +410,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
         var quote = next(), ret = "";
         for (;;) {
             var ch = next(true, true);
-            if (ch == "\\") {
-                var octal_len = 0, first = null;
-                ch = read_while(function(ch){
-                    if (ch >= "0" && ch <= "7") {
-                        if (!first) {
-                            first = ch;
-                            return ++octal_len;
-                        }
-                        else if (first <= "3" && octal_len <= 2) return ++octal_len;
-                        else if (first >= "4" && octal_len <= 1) return ++octal_len;
-                    }
-                    return false;
-                });
-                if (octal_len > 0) {
-                    if (ch !== "0" && next_token.has_directive("use strict"))
-                        parse_error("Octal literals are not allowed in strict mode");
-                    ch = String.fromCharCode(parseInt(ch, 8));
-                } else {
-                    ch = read_escaped_char(true);
-                }
-            }
+            if (ch == "\\") ch = read_escaped_char(true);
             else if ("\r\n\u2028\u2029".indexOf(ch) >= 0) parse_error("Unterminated string constant");
             else if (ch == quote) break;
             ret += ch;
diff --git a/test/compress/string-literal.js b/test/compress/string-literal.js
new file mode 100644 (file)
index 0000000..8b93961
--- /dev/null
@@ -0,0 +1,10 @@
+octal_escape_sequence: {
+    input: {
+        var boundaries = "\0\7\00\07\70\77\000\077\300\377";
+        var border_check = "\400\700\0000\3000";
+    }
+    expect: {
+        var boundaries = "\x00\x07\x00\x07\x38\x3f\x00\x3f\xc0\xff";
+        var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
+    }
+}
index ea98421..d427472 100644 (file)
@@ -49,7 +49,7 @@ describe("String literals", function() {
 
         var error = function(e) {
             return e instanceof UglifyJS.JS_Parse_Error &&
-                e.message === "Octal literals are not allowed in strict mode";
+                e.message === "SyntaxError: Octal literals are not allowed in strict mode";
         }
 
         for (var input in inputs) {