[Pkg-javascript-commits] [uglifyjs] 07/50: fix label-related bugs (#1835)

Jonas Smedegaard dr at jones.dk
Thu Aug 17 23:06:43 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository uglifyjs.

commit d8106b6c6320d4ccfb2a00fb518c297c207e4900
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sat Apr 22 22:15:04 2017 +0800

    fix label-related bugs (#1835)
    
    - deep cloning of `AST_LabeledStatement`
    - `L:do{...}while(false)`
    - empty statement with label within block
    
    extend `test/ufuzz.js`
    - generate labels for blocks & loops
    - generate for-in statements
    - skip suspicious option search if `minify()` errs
    
    fixes #1833
---
 lib/ast.js                  |   9 +--
 lib/compress.js             |  11 ++--
 lib/output.js               |  10 +---
 test/compress/issue-1833.js | 134 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 148 insertions(+), 16 deletions(-)

diff --git a/lib/ast.js b/lib/ast.js
index ba1330f..cdf75d4 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -214,12 +214,13 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
     clone: function(deep) {
         var node = this._clone(deep);
         if (deep) {
-            var refs = node.label.references;
-            var label = this.label;
+            var label = node.label;
+            var def = this.label;
             node.walk(new TreeWalker(function(node) {
                 if (node instanceof AST_LoopControl
-                    && node.label && node.label.thedef === label) {
-                    refs.push(node);
+                    && node.label && node.label.thedef === def) {
+                    node.label.thedef = label;
+                    label.references.push(node);
                 }
             }));
         }
diff --git a/lib/compress.js b/lib/compress.js
index 14c419b..8454a43 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2404,7 +2404,7 @@ merge(Compressor.prototype, {
             if (compressor.option("dead_code") && self instanceof AST_While) {
                 var a = [];
                 extract_declarations_from_unreachable_code(compressor, self.body, a);
-                return make_node(AST_BlockStatement, self, { body: a });
+                return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
             }
             if (self instanceof AST_Do) {
                 var has_loop_control = false;
@@ -2413,7 +2413,8 @@ merge(Compressor.prototype, {
                     if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self)
                         return has_loop_control = true;
                 });
-                self.walk(tw);
+                var parent = compressor.parent();
+                (parent instanceof AST_LabeledStatement ? parent : self).walk(tw);
                 if (!has_loop_control) return self.body;
             }
         }
@@ -2483,7 +2484,7 @@ merge(Compressor.prototype, {
                     }));
                 }
                 extract_declarations_from_unreachable_code(compressor, self.body, a);
-                return make_node(AST_BlockStatement, self, { body: a });
+                return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
             }
             if (cond !== self.condition) {
                 cond = make_node_from_constant(cond, self.condition).transform(compressor);
@@ -2735,9 +2736,9 @@ merge(Compressor.prototype, {
             var body = [];
             if (self.bcatch) extract_declarations_from_unreachable_code(compressor, self.bcatch, body);
             if (self.bfinally) body = body.concat(self.bfinally.body);
-            return body.length > 0 ? make_node(AST_BlockStatement, self, {
+            return make_node(AST_BlockStatement, self, {
                 body: body
-            }).optimize(compressor) : make_node(AST_EmptyStatement, self);
+            }).optimize(compressor);
         }
         return self;
     });
diff --git a/lib/output.js b/lib/output.js
index 9ac50c0..0731fb4 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -190,11 +190,7 @@ function OutputStream(options) {
     var might_need_space = false;
     var might_need_semicolon = false;
     var might_add_newline = 0;
-    var last = null;
-
-    function last_char() {
-        return last.charAt(last.length - 1);
-    };
+    var last = "";
 
     var ensure_line_len = options.max_line_len ? function() {
         if (current_col > options.max_line_len) {
@@ -218,10 +214,11 @@ function OutputStream(options) {
     function print(str) {
         str = String(str);
         var ch = str.charAt(0);
+        var prev = last.charAt(last.length - 1);
         if (might_need_semicolon) {
             might_need_semicolon = false;
 
-            if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) {
+            if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
                 if (options.semicolons || requireSemicolonChars(ch)) {
                     OUTPUT += ";";
                     current_col++;
@@ -258,7 +255,6 @@ function OutputStream(options) {
         }
 
         if (might_need_space) {
-            var prev = last_char();
             if ((is_identifier_char(prev)
                     && (is_identifier_char(ch) || ch == "\\"))
                 || (ch == "/" && ch == prev)
diff --git a/test/compress/issue-1833.js b/test/compress/issue-1833.js
new file mode 100644
index 0000000..e46dd04
--- /dev/null
+++ b/test/compress/issue-1833.js
@@ -0,0 +1,134 @@
+iife_for: {
+    options = {
+        negate_iife: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function f() {
+            function g() {
+                L: for (;;) break L;
+            }
+            g();
+        }
+        f();
+    }
+    expect: {
+        !function() {
+            !function() {
+                L: for (;;) break L;
+            }();
+        }();
+    }
+}
+
+iife_for_in: {
+    options = {
+        negate_iife: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function f() {
+            function g() {
+                L: for (var a in x) break L;
+            }
+            g();
+        }
+        f();
+    }
+    expect: {
+        !function() {
+            !function() {
+                L: for (var a in x) break L;
+            }();
+        }();
+    }
+}
+
+iife_do: {
+    options = {
+        negate_iife: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function f() {
+            function g() {
+                L: do {
+                    break L;
+                } while (1);
+            }
+            g();
+        }
+        f();
+    }
+    expect: {
+        !function() {
+            !function() {
+                L: do {
+                    break L;
+                } while (1);
+            }();
+        }();
+    }
+}
+
+iife_while: {
+    options = {
+        negate_iife: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function f() {
+            function g() {
+                L: while (1) break L;
+            }
+            g();
+        }
+        f();
+    }
+    expect: {
+        !function() {
+            !function() {
+                L: while (1) break L;
+            }();
+        }();
+    }
+}
+
+label_do: {
+    options = {
+        evaluate: true,
+        loops: true,
+    }
+    input: {
+        L: do {
+            continue L;
+        } while (0);
+    }
+    expect: {
+        L: do {
+            continue L;
+        } while (0);
+    }
+}
+
+label_while: {
+    options = {
+        evaluate: true,
+        dead_code: true,
+        loops: true,
+    }
+    input: {
+        function f() {
+            L: while (0) continue L;
+        }
+    }
+    expect_exact: "function f(){L:;}"
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list