aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnthony Van de Gejuchte <anthonyvdgent@gmail.com>2016-06-13 21:11:08 +0200
committerRichard van Velzen <rvanvelzen1@gmail.com>2016-06-19 20:59:17 +0200
commit2149bfb7071dedbcd42d2e245bb9c2f6b41a43bc (patch)
tree0d389df29100365c26b97224ba436c5b0dbd222c /lib
parentd7971ba0e439eb042fd880762bc7fa77ce1f3e73 (diff)
downloadtracifyjs-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.js42
-rw-r--r--lib/parse.js8
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: