diff options
author | Anthony Van de Gejuchte <anthonyvdgent@gmail.com> | 2016-05-20 10:25:35 +0200 |
---|---|---|
committer | Richard van Velzen <rvanvelzen@experty.com> | 2016-06-12 14:27:08 +0200 |
commit | 4d7746baf31405427209de0d8c44d9c8263a2563 (patch) | |
tree | c86706395e8852fafbd846c438e73c5a3a0e9659 /lib | |
parent | 31d5825a86a6bcee91187b4a3962e0cd0f3b0d93 (diff) | |
download | tracifyjs-4d7746baf31405427209de0d8c44d9c8263a2563.tar.gz tracifyjs-4d7746baf31405427209de0d8c44d9c8263a2563.zip |
Throw errors in strict mode for octal strings
Adds a directive tracker for the parser/tokenizer to
allow parsing depending on directive context.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/parse.js | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/lib/parse.js b/lib/parse.js index 467fc60b..4530c2d9 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -223,7 +223,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { tokcol : 0, newline_before : false, regex_allowed : false, - comments_before : [] + comments_before : [], + directives : {}, + directive_stack : [] }; function peek() { return S.text.charAt(S.pos); }; @@ -392,8 +394,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { for (;;) { var ch = next(true, true); if (ch == "\\") { - // read OctalEscapeSequence (XXX: deprecated if "strict mode") - // https://github.com/mishoo/UglifyJS/issues/178 var octal_len = 0, first = null; ch = read_while(function(ch){ if (ch >= "0" && ch <= "7") { @@ -406,8 +406,13 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { } return false; }); - if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8)); - else ch = read_escaped_char(true); + 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); + } } else if ("\r\n\u2028\u2029".indexOf(ch) >= 0) parse_error("Unterminated string constant"); else if (ch == quote) break; @@ -608,6 +613,35 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { return S; }; + next_token.add_directive = function(directive) { + S.directive_stack[S.directive_stack.length - 1].push(directive); + + if (S.directives[directive] === undefined) { + S.directives[directive] = 1; + } else { + S.directives[directive]++; + } + } + + next_token.push_directives_stack = function() { + S.directive_stack.push([]); + } + + next_token.pop_directives_stack = function() { + var directives = S.directive_stack[S.directive_stack.length - 1]; + + for (var i = 0; i < directives.length; i++) { + S.directives[directives[i]]--; + } + + S.directive_stack.pop(); + } + + next_token.has_directive = function(directive) { + return S.directives[directive] !== undefined && + S.directives[directive] > 0; + } + return next_token; }; @@ -781,9 +815,15 @@ function parse($TEXT, options) { handle_regexp(); switch (S.token.type) { case "string": + if (S.in_directives) { + if (is_token(peek(), "punc", ";") || peek().nlb) { + S.input.add_directive(S.token.raw.substr(1, S.token.raw.length - 2)); + } else { + S.in_directives = false; + } + } var dir = S.in_directives, stat = simple_statement(); - // XXXv2: decide how to fix directives - if (dir && stat.body instanceof AST_String && !is("punc", ",")) { + if (dir) { return new AST_Directive({ start : stat.body.start, end : stat.body.end, @@ -1012,9 +1052,11 @@ function parse($TEXT, options) { body: (function(loop, labels){ ++S.in_function; S.in_directives = true; + S.input.push_directives_stack(); S.in_loop = 0; S.labels = []; var a = block_(); + S.input.pop_directives_stack(); --S.in_function; S.in_loop = loop; S.labels = labels; @@ -1514,8 +1556,10 @@ function parse($TEXT, options) { return (function(){ var start = S.token; var body = []; + S.input.push_directives_stack(); while (!is("eof")) body.push(statement()); + S.input.pop_directives_stack(); var end = prev(); var toplevel = options.toplevel; if (toplevel) { |