Prevent endless recursion when evaluating self-referencing consts
authorRichard van Velzen <rvanvelzen@experty.com>
Tue, 12 Apr 2016 18:30:44 +0000 (20:30 +0200)
committerRichard van Velzen <rvanvelzen@experty.com>
Wed, 13 Apr 2016 13:03:31 +0000 (15:03 +0200)
Fix #1041

lib/compress.js
test/compress/issue-1041.js [new file with mode: 0644]

index 153e70f..3e33c1b 100644 (file)
@@ -1030,8 +1030,16 @@ merge(Compressor.prototype, {
                 : ev(this.alternative, compressor);
         });
         def(AST_SymbolRef, function(compressor){
-            var d = this.definition();
-            if (d && d.constant && d.init) return ev(d.init, compressor);
+            if (this._evaluating) throw def;
+            this._evaluating = true;
+            try {
+                var d = this.definition();
+                if (d && d.constant && d.init) {
+                    return ev(d.init, compressor);
+                }
+            } finally {
+                this._evaluating = false;
+            }
             throw def;
         });
         def(AST_Dot, function(compressor){
diff --git a/test/compress/issue-1041.js b/test/compress/issue-1041.js
new file mode 100644 (file)
index 0000000..9dd176f
--- /dev/null
@@ -0,0 +1,39 @@
+const_declaration: {
+    options = {
+        evaluate: true
+    };
+
+    input: {
+        const goog = goog || {};
+    }
+    expect: {
+        const goog = goog || {};
+    }
+}
+
+const_pragma: {
+    options = {
+        evaluate: true
+    };
+
+    input: {
+        /** @const */ var goog = goog || {};
+    }
+    expect: {
+        var goog = goog || {};
+    }
+}
+
+// for completeness' sake
+not_const: {
+    options = {
+        evaluate: true
+    };
+
+    input: {
+        var goog = goog || {};
+    }
+    expect: {
+        var goog = goog || {};
+    }
+}