From 149d75c09273ec1cb7e2d04d46d2b9be26ae91bf Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 15 Mar 2021 09:51:32 +0000 Subject: [PATCH] fix corner case in `unsafe` (#4779) --- lib/compress.js | 17 +++++++++----- test/compress/spreads.js | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index bdd3c94876..0d87e308d7 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8533,20 +8533,25 @@ merge(Compressor.prototype, { var separator = self.args[0]; // [].join() ---> "" // [].join(x) ---> (x, "") - if (exp.expression.elements.length == 0) return separator ? make_sequence(self, [ - separator, - make_node(AST_String, self, { value: "" }), - ]).optimize(compressor) : make_node(AST_String, self, { value: "" }); + if (exp.expression.elements.length == 0 && !(separator instanceof AST_Spread)) { + return separator ? make_sequence(self, [ + separator, + make_node(AST_String, self, { value: "" }), + ]).optimize(compressor) : make_node(AST_String, self, { value: "" }); + } if (separator) { separator = separator.evaluate(compressor); if (separator instanceof AST_Node) break EXIT; // not a constant } var elements = []; var consts = []; - exp.expression.elements.forEach(function(el) { + for (var i = 0; i < exp.expression.elements.length; i++) { + var el = exp.expression.elements[i]; var value = el.evaluate(compressor); if (value !== el) { consts.push(value); + } else if (el instanceof AST_Spread) { + break EXIT; } else { if (consts.length > 0) { elements.push(make_node(AST_String, self, { @@ -8556,7 +8561,7 @@ merge(Compressor.prototype, { } elements.push(el); } - }); + } if (consts.length > 0) elements.push(make_node(AST_String, self, { value: consts.join(separator), })); diff --git a/test/compress/spreads.js b/test/compress/spreads.js index ba10167a60..f8c0d59223 100644 --- a/test/compress/spreads.js +++ b/test/compress/spreads.js @@ -689,6 +689,57 @@ unused_var_side_effects: { node_version: ">=8" } +unsafe_join_1: { + options = { + unsafe: true, + } + input: { + console.log([ ..."foo" ].join()); + } + expect: { + console.log([ ..."foo" ].join()); + } + expect_stdout: "f,o,o" + node_version: ">=6" +} + +unsafe_join_2: { + options = { + evaluate: true, + unsafe: true, + } + input: { + console.log([ "foo", ..."bar" ].join("")); + } + expect: { + console.log([ "foo", ..."bar" ].join("")); + } + expect_stdout: "foobar" + node_version: ">=6" +} + +unsafe_join_3: { + options = { + unsafe: true, + } + input: { + try { + [].join(...console); + } catch (e) { + console.log("PASS"); + } + } + expect: { + try { + [].join(...console); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + issue_4329: { options = { objects: true,