Skip to content

Commit

Permalink
fix corner case in parsing directives (#3615)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Nov 29, 2019
1 parent 1b61a81 commit 1283d73
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 71 deletions.
26 changes: 13 additions & 13 deletions lib/parse.js
Expand Up @@ -787,20 +787,18 @@ function parse($TEXT, options) {
handle_regexp();
switch (S.token.type) {
case "string":
if (S.in_directives) {
var token = peek();
if (S.token.raw.indexOf("\\") == -1
&& (is_token(token, "punc", ";")
|| is_token(token, "punc", "}")
|| has_newline_before(token)
|| is_token(token, "eof"))) {
S.input.add_directive(S.token.value);
var dir = S.in_directives;
var body = expression(true);
if (dir) {
var token = body.start;
if (body instanceof AST_String && token.raw.indexOf("\\") == -1) {
S.input.add_directive(token.value);
} else {
S.in_directives = false;
S.in_directives = dir = false;
}
}
var dir = S.in_directives, stat = simple_statement();
return dir ? new AST_Directive(stat.body) : stat;
semicolon();
return dir ? new AST_Directive(body) : new AST_SimpleStatement({ body: body });
case "num":
case "regexp":
case "operator":
Expand Down Expand Up @@ -965,8 +963,10 @@ function parse($TEXT, options) {
return new AST_LabeledStatement({ body: stat, label: label });
}

function simple_statement(tmp) {
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
function simple_statement() {
var body = expression(true);
semicolon();
return new AST_SimpleStatement({ body: body });
}

function break_cont(type) {
Expand Down
95 changes: 95 additions & 0 deletions test/compress/directives.js
@@ -0,0 +1,95 @@
simple_statement_is_not_a_directive: {
input: {
"use strict"
.split(" ")
.forEach(function(s) {
console.log(s);
});
console.log(!this); // is strict mode?
(function() {
"directive"
""
"use strict"
"hello world"
.split(" ")
.forEach(function(s) {
console.log(s);
});
console.log(!this); // is strict mode?
})();
}
expect: {
"use strict".split(" ").forEach(function(s) {
console.log(s);
});
console.log(!this);
(function() {
"directive";
"";
"use strict";
"hello world".split(" ").forEach(function(s) {
console.log(s);
});
console.log(!this);
})();
}
expect_stdout: [
"use",
"strict",
"false",
"hello",
"world",
"true",
]
}

drop_lone_use_strict: {
options = {
directives: true,
side_effects: true,
}
input: {
function f1() {
"use strict";
}
function f2() {
"use strict";
function f3() {
"use strict";
}
}
(function f4() {
"use strict";
})();
}
expect: {
function f1() {
}
function f2() {
"use strict";
function f3() {
}
}
}
}

issue_3166: {
options = {
directives: true,
}
input: {
"foo";
"use strict";
function f() {
"use strict";
"bar";
"use asm";
}
}
expect: {
"use strict";
function f() {
"use asm";
}
}
}
51 changes: 0 additions & 51 deletions test/compress/functions.js
Expand Up @@ -2004,57 +2004,6 @@ deduplicate_parenthesis: {
expect_exact: "({}).a=b;({}.a=b)();(function(){}).a=b;(function(){}.a=b)();"
}

drop_lone_use_strict: {
options = {
directives: true,
side_effects: true,
}
input: {
function f1() {
"use strict";
}
function f2() {
"use strict";
function f3() {
"use strict";
}
}
(function f4() {
"use strict";
})();
}
expect: {
function f1() {
}
function f2() {
"use strict";
function f3() {
}
}
}
}

issue_3166: {
options = {
directives: true,
}
input: {
"foo";
"use strict";
function f() {
"use strict";
"bar";
"use asm";
}
}
expect: {
"use strict";
function f() {
"use asm";
}
}
}

issue_3016_1: {
options = {
inline: true,
Expand Down
12 changes: 6 additions & 6 deletions test/mocha/directives.js
Expand Up @@ -54,8 +54,8 @@ describe("Directives", function() {
[
[
'"use strict"\n',
[ "use strict"],
[ "use asm"]
[ "use strict" ],
[ "use asm" ]
],
[
'"use\\\nstrict";',
Expand All @@ -80,8 +80,8 @@ describe("Directives", function() {
[
// no ; or newline
'"use strict"',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
[ "use strict" ],
[ "use\nstrict", "use \nstrict", "use asm" ]
],
[
';"use strict"',
Expand Down Expand Up @@ -116,8 +116,8 @@ describe("Directives", function() {
],
[
'var foo = function() {"use strict"', // no ; or newline
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
[ "use strict" ],
[ "use\nstrict", "use \nstrict", "use asm" ]
],
[
'var foo = function() {;"use strict"',
Expand Down
10 changes: 9 additions & 1 deletion test/mocha/number-literal.js
Expand Up @@ -2,10 +2,18 @@ var assert = require("assert");
var UglifyJS = require("../node");

describe("Number literals", function() {
it("Should allow legacy octal literals in non-strict mode", function() {
[
"'use strict'\n.slice()\n00",
'"use strict"\n.slice()\nvar foo = 00',
].forEach(function(input) {
UglifyJS.parse(input);
});
});
it("Should not allow legacy octal literals in strict mode", function() {
var inputs = [
'"use strict";00;',
'"use strict"; var foo = 00;'
'"use strict"; var foo = 00;',
];
var test = function(input) {
return function() {
Expand Down

0 comments on commit 1283d73

Please sign in to comment.