diff options
author | Anthony Van de Gejuchte <anthonyvdgent@gmail.com> | 2016-06-13 21:11:08 +0200 |
---|---|---|
committer | Richard van Velzen <rvanvelzen1@gmail.com> | 2016-06-19 20:59:17 +0200 |
commit | 2149bfb7071dedbcd42d2e245bb9c2f6b41a43bc (patch) | |
tree | 0d389df29100365c26b97224ba436c5b0dbd222c /lib | |
parent | d7971ba0e439eb042fd880762bc7fa77ce1f3e73 (diff) | |
download | tracifyjs-2149bfb7071dedbcd42d2e245bb9c2f6b41a43bc.tar.gz tracifyjs-2149bfb7071dedbcd42d2e245bb9c2f6b41a43bc.zip |
Don't mix strings with directives in output
* Don't interpret strings with escaped content as directive
* Don't interpret strings after empty statement as directive
* Adapt output to prevent strings being represent as directive
* Introduce UGLIFY_DEBUG to allow internal testing like EXPECT_DIRECTIVE
Diffstat (limited to 'lib')
-rw-r--r-- | lib/output.js | 42 | ||||
-rw-r--r-- | lib/parse.js | 8 |
2 files changed, 40 insertions, 10 deletions
diff --git a/lib/output.js b/lib/output.js index 6eae2f1f..1fa9899f 100644 --- a/lib/output.js +++ b/lib/output.js @@ -43,6 +43,8 @@ "use strict"; +var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/; + function OutputStream(options) { options = defaults(options, { @@ -354,7 +356,18 @@ function OutputStream(options) { force_semicolon : force_semicolon, to_ascii : to_ascii, print_name : function(name) { print(make_name(name)) }, - print_string : function(str, quote) { print(encode_string(str, quote)) }, + print_string : function(str, quote, escape_directive) { + var encoded = encode_string(str, quote); + if (escape_directive === true && encoded.indexOf("\\") === -1) { + // Insert semicolons to break directive prologue + if (!EXPECT_DIRECTIVE.test(OUTPUT)) { + force_semicolon(); + } + force_semicolon(); + } + print(encoded); + }, + encode_string : encode_string, next_indent : next_indent, with_indent : with_indent, with_block : with_block, @@ -386,6 +399,7 @@ function OutputStream(options) { }; var use_asm = false; + var in_directive = false; AST_Node.DEFMETHOD("print", function(stream, force_parens){ var self = this, generator = self._codegen, prev_use_asm = use_asm; @@ -642,9 +656,16 @@ function OutputStream(options) { /* -----[ statements ]----- */ - function display_body(body, is_toplevel, output) { + function display_body(body, is_toplevel, output, allow_directives) { var last = body.length - 1; + in_directive = allow_directives; body.forEach(function(stmt, i){ + if (in_directive === true && !(stmt instanceof AST_Directive || + stmt instanceof AST_EmptyStatement || + (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) + )) { + in_directive = false; + } if (!(stmt instanceof AST_EmptyStatement)) { output.indent(); stmt.print(output); @@ -653,7 +674,14 @@ function OutputStream(options) { if (is_toplevel) output.newline(); } } + if (in_directive === true && + stmt instanceof AST_SimpleStatement && + stmt.body instanceof AST_String + ) { + in_directive = false; + } }); + in_directive = false; }; AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){ @@ -665,7 +693,7 @@ function OutputStream(options) { output.semicolon(); }); DEFPRINT(AST_Toplevel, function(self, output){ - display_body(self.body, true, output); + display_body(self.body, true, output, true); output.print(""); }); DEFPRINT(AST_LabeledStatement, function(self, output){ @@ -677,9 +705,9 @@ function OutputStream(options) { self.body.print(output); output.semicolon(); }); - function print_bracketed(body, output) { + function print_bracketed(body, output, allow_directives) { if (body.length > 0) output.with_block(function(){ - display_body(body, false, output); + display_body(body, false, output, allow_directives); }); else output.print("{}"); }; @@ -779,7 +807,7 @@ function OutputStream(options) { }); }); output.space(); - print_bracketed(self.body, output); + print_bracketed(self.body, output, true); }); DEFPRINT(AST_Lambda, function(self, output){ self._do_print(output); @@ -1185,7 +1213,7 @@ function OutputStream(options) { output.print(self.getValue()); }); DEFPRINT(AST_String, function(self, output){ - output.print_string(self.getValue(), self.quote); + output.print_string(self.getValue(), self.quote, in_directive); }); DEFPRINT(AST_Number, function(self, output){ if (use_asm && self.start.raw != null) { diff --git a/lib/parse.js b/lib/parse.js index 2c007965..9b5a142b 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -815,9 +815,10 @@ 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)); + var dir = false; + if (S.in_directives === true) { + if ((is_token(peek(), "punc", ";") || peek().nlb) && S.token.raw.indexOf("\\") === -1) { + S.input.add_directive(S.token.value); } else { S.in_directives = false; } @@ -855,6 +856,7 @@ function parse($TEXT, options) { case "(": return simple_statement(); case ";": + S.in_directives = false; next(); return new AST_EmptyStatement(); default: |