fix corner case in `unsafe` (#4779)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 15 Mar 2021 09:51:32 +0000 (09:51 +0000)
committerGitHub <noreply@github.com>
Mon, 15 Mar 2021 09:51:32 +0000 (17:51 +0800)
lib/compress.js
test/compress/spreads.js

index bdd3c94..0d87e30 100644 (file)
@@ -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),
                     }));
index ba10167..f8c0d59 100644 (file)
@@ -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,