aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnthony Van de Gejuchte <anthonyvdgent@gmail.com>2016-05-20 10:25:35 +0200
committerRichard van Velzen <rvanvelzen@experty.com>2016-06-12 14:27:08 +0200
commit4d7746baf31405427209de0d8c44d9c8263a2563 (patch)
treec86706395e8852fafbd846c438e73c5a3a0e9659 /lib
parent31d5825a86a6bcee91187b4a3962e0cd0f3b0d93 (diff)
downloadtracifyjs-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.js58
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) {