From: Alex Lam S.L Date: Fri, 10 Apr 2020 22:36:17 +0000 (+0100) Subject: improve handling of `eval` (#3776) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=c810ecd0810c86dc9cd25b443c33aa998649e390;p=UglifyJS.git improve handling of `eval` (#3776) closes #3768 --- diff --git a/lib/compress.js b/lib/compress.js index e9f83731..98724bd0 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -996,9 +996,7 @@ merge(Compressor.prototype, { function needs_unbinding(compressor, val) { return val instanceof AST_PropAccess - || compressor.has_directive("use strict") - && is_undeclared_ref(val) - && val.name == "eval"; + || is_undeclared_ref(val) && val.name == "eval"; } // we shouldn't compress (1,func)(something) to diff --git a/lib/scope.js b/lib/scope.js index 35d97e12..ad33c5e0 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -162,17 +162,22 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } if (node instanceof AST_SymbolRef) { var name = node.name; - if (name == "eval" && tw.parent() instanceof AST_Call) { - for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) { - s.uses_eval = true; - } - } var sym = node.scope.find_variable(name); if (!sym) { sym = self.def_global(node); } else if (sym.scope instanceof AST_Lambda && name == "arguments") { sym.scope.uses_arguments = true; } + if (name == "eval") { + var parent = tw.parent(); + if (parent.TYPE == "Call" && parent.expression === node) { + for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) { + s.uses_eval = true; + } + } else if (sym.undeclared) { + self.uses_eval = true; + } + } node.thedef = sym; node.reference(options); return true; diff --git a/test/compress/issue-3768.js b/test/compress/issue-3768.js index c3475aca..c467fa64 100644 --- a/test/compress/issue-3768.js +++ b/test/compress/issue-3768.js @@ -9,12 +9,12 @@ mangle: { })(); } expect: { - var o = eval, e = 42; + var e = eval, x = 42; (function() { - console.log(o("typeof x")); + console.log(e("typeof x")); })(); } - expect_stdout: "undefined" + expect_stdout: true } compress: { @@ -49,7 +49,7 @@ compress: { console.log(function() { var a = 42; return eval("typeof a"); - }(), eval("typeof a"), function(eval) { + }(), (0, eval)("typeof a"), function(eval) { var a = false; return eval("typeof a"); }(eval), function(f) { @@ -66,3 +66,63 @@ compress: { } expect_stdout: "number undefined boolean string undefined" } + +call_arg_1: { + mangle = { + toplevel: true, + } + input: { + var z = "foo"; + (function() { + var z = false; + (function(e) { + var z = 42; + e("console.log(typeof z)"); + })(eval); + })(); + } + expect: { + var z = "foo"; + (function() { + var o = false; + (function(o) { + var a = 42; + o("console.log(typeof z)"); + })(eval); + })(); + } + expect_stdout: true +} + +call_arg_2: { + mangle = { + toplevel: true, + } + input: { + function eval() { + console.log("PASS"); + } + var z = "foo"; + (function() { + var z = false; + (function(e) { + var z = 42; + e("console.log(typeof z)"); + })(eval); + })(); + } + expect: { + function n() { + console.log("PASS"); + } + var o = "foo"; + (function() { + var o = false; + (function(o) { + var n = 42; + o("console.log(typeof z)"); + })(n); + })(); + } + expect_stdout: "PASS" +} diff --git a/test/compress/issue-782.js b/test/compress/issue-782.js index 6e1c92f5..34baf5ff 100644 --- a/test/compress/issue-782.js +++ b/test/compress/issue-782.js @@ -8,7 +8,7 @@ remove_sequence: { (0, 1, _decorators.logThis)(); } expect: { - eval(); + (0, eval)(); logThis(); (0, _decorators.logThis)(); } diff --git a/test/compress/issue-973.js b/test/compress/issue-973.js index e127c10c..93071107 100644 --- a/test/compress/issue-973.js +++ b/test/compress/issue-973.js @@ -53,20 +53,23 @@ this_binding_conditionals: { this_binding_collapse_vars: { options = { collapse_vars: true, - toplevel: true, unused: true, } input: { - "use strict"; - var c = a; c(); - var d = a.b; d(); - var e = eval; e(); + function f() { + "use strict"; + var c = a; c(); + var d = a.b; d(); + var e = eval; e(); + } } expect: { - "use strict"; - a(); - (0, a.b)(); - (0, eval)(); + function f() { + "use strict"; + a(); + (0, a.b)(); + (0, eval)(); + } } } @@ -97,7 +100,7 @@ this_binding_side_effects: { (function(foo) { foo(); (0, foo.bar)(); - eval("console.log(foo);"); + (0, eval)("console.log(foo);"); }()); (function(foo) { "use strict"; @@ -144,7 +147,7 @@ this_binding_sequences: { return eval("this"); }()), console.log(typeof function() { - return eval("this"); + return (0, eval)("this"); }()), console.log(typeof function() { "use strict";