[Pkg-javascript-commits] [uglifyjs] 395/491: fix `mangle` name collision across files (#2722)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:56 UTC 2018


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

js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.

commit afbcebddf63c7ffa5b0df9b3712ee3b560918f1e
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Fri Jan 5 05:08:09 2018 +0800

    fix `mangle` name collision across files (#2722)
---
 lib/minify.js                |  2 --
 lib/propmangle.js            | 25 ++++++++++++---------
 lib/scope.js                 | 34 ++++++++++++++++++----------
 test/input/issue-1242/qux.js |  6 ++---
 test/mocha/minify.js         | 53 +++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/lib/minify.js b/lib/minify.js
index 806c3ae..a68cbf3 100644
--- a/lib/minify.js
+++ b/lib/minify.js
@@ -29,7 +29,6 @@ function set_shorthand(name, options, keys) {
 
 function init_cache(cache) {
     if (!cache) return;
-    if (!("cname" in cache)) cache.cname = -1;
     if (!("props" in cache)) {
         cache.props = new Dictionary();
     } else if (!(cache.props instanceof Dictionary)) {
@@ -39,7 +38,6 @@ function init_cache(cache) {
 
 function to_json(cache) {
     return {
-        cname: cache.cname,
         props: cache.props.toObject()
     };
 }
diff --git a/lib/propmangle.js b/lib/propmangle.js
index c2f27c4..ffc8faf 100644
--- a/lib/propmangle.js
+++ b/lib/propmangle.js
@@ -110,12 +110,15 @@ function mangle_properties(ast, options) {
     if (!Array.isArray(reserved)) reserved = [];
     if (!options.builtins) find_builtins(reserved);
 
-    var cache = options.cache;
-    if (cache == null) {
-        cache = {
-            cname: -1,
-            props: new Dictionary()
-        };
+    var cname = -1;
+    var cache;
+    if (options.cache) {
+        cache = options.cache.props;
+        cache.each(function(mangled_name) {
+            push_uniq(reserved, mangled_name);
+        });
+    } else {
+        cache = new Dictionary();
     }
 
     var regex = options.regex;
@@ -172,7 +175,7 @@ function mangle_properties(ast, options) {
         if (unmangleable.indexOf(name) >= 0) return false;
         if (reserved.indexOf(name) >= 0) return false;
         if (options.only_cache) {
-            return cache.props.has(name);
+            return cache.has(name);
         }
         if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
         return true;
@@ -181,7 +184,7 @@ function mangle_properties(ast, options) {
     function should_mangle(name) {
         if (regex && !regex.test(name)) return false;
         if (reserved.indexOf(name) >= 0) return false;
-        return cache.props.has(name)
+        return cache.has(name)
             || names_to_mangle.indexOf(name) >= 0;
     }
 
@@ -199,7 +202,7 @@ function mangle_properties(ast, options) {
             return name;
         }
 
-        var mangled = cache.props.get(name);
+        var mangled = cache.get(name);
         if (!mangled) {
             if (debug) {
                 // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
@@ -213,11 +216,11 @@ function mangle_properties(ast, options) {
             // either debug mode is off, or it is on and we could not use the mangled name
             if (!mangled) {
                 do {
-                    mangled = base54(++cache.cname);
+                    mangled = base54(++cname);
                 } while (!can_mangle(mangled));
             }
 
-            cache.props.set(name, mangled);
+            cache.set(name, mangled);
         }
         return mangled;
     }
diff --git a/lib/scope.js b/lib/scope.js
index de92fc9..801c888 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -242,10 +242,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
             }
         }));
     }
-
-    if (options.cache) {
-        this.cname = options.cache.cname;
-    }
 });
 
 AST_Toplevel.DEFMETHOD("def_global", function(node){
@@ -329,10 +325,10 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
     return symbol.thedef = def;
 });
 
-AST_Scope.DEFMETHOD("next_mangled", function(options){
-    var ext = this.enclosed;
+function next_mangled(scope, options) {
+    var ext = scope.enclosed;
     out: while (true) {
-        var m = base54(++this.cname);
+        var m = base54(++scope.cname);
         if (!is_identifier(m)) continue; // skip over "do"
 
         // https://github.com/mishoo/UglifyJS2/issues/242 -- do not
@@ -349,6 +345,18 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
         }
         return m;
     }
+}
+
+AST_Scope.DEFMETHOD("next_mangled", function(options){
+    return next_mangled(this, options);
+});
+
+AST_Toplevel.DEFMETHOD("next_mangled", function(options){
+    var name;
+    do {
+        name = next_mangled(this, options);
+    } while (member(name, this.mangled_names));
+    return name;
 });
 
 AST_Function.DEFMETHOD("next_mangled", function(options, def){
@@ -362,7 +370,7 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
     var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
 
     while (true) {
-        var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
+        var name = next_mangled(this, options);
         if (!tricky_name || tricky_name != name)
             return name;
     }
@@ -413,8 +421,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
     var lname = -1;
     var to_mangle = [];
 
+    var mangled_names = this.mangled_names = [];
     if (options.cache) {
         this.globals.each(collect);
+        if (options.cache.props) {
+            options.cache.props.each(function(mangled_name) {
+                push_uniq(mangled_names, mangled_name);
+            });
+        }
     }
 
     var tw = new TreeWalker(function(node, descend){
@@ -443,10 +457,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
     this.walk(tw);
     to_mangle.forEach(function(def){ def.mangle(options) });
 
-    if (options.cache) {
-        options.cache.cname = this.cname;
-    }
-
     function collect(symbol) {
         if (!member(symbol.name, options.reserved)) {
             to_mangle.push(symbol);
diff --git a/test/input/issue-1242/qux.js b/test/input/issue-1242/qux.js
index 94171f3..4a72ffc 100644
--- a/test/input/issue-1242/qux.js
+++ b/test/input/issue-1242/qux.js
@@ -1,4 +1,4 @@
-var a = bar(1+2);
-var b = baz(3+9);
-print('q' + 'u' + 'x', a, b);
+var x = bar(1+2);
+var y = baz(3+9);
+print('q' + 'u' + 'x', x, y);
 foo(5+6);
diff --git a/test/mocha/minify.js b/test/mocha/minify.js
index 5fa9254..a304c5b 100644
--- a/test/mocha/minify.js
+++ b/test/mocha/minify.js
@@ -42,8 +42,15 @@ describe("minify", function() {
             original += code;
             compressed += result.code;
         });
-        assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
-        assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
+        assert.strictEqual(JSON.stringify(cache).slice(0, 10), '{"props":{');
+        assert.strictEqual(compressed, [
+            "function n(n){return 3*n}",
+            "function r(n){return n/2}",
+            "var o=console.log.bind(console);",
+            'function c(n){o("Foo:",2*n)}',
+            "var a=n(3),b=r(12);",
+            'o("qux",a,b),c(11);',
+        ].join(""));
         assert.strictEqual(run_code(compressed), run_code(original));
     });
 
@@ -68,12 +75,48 @@ describe("minify", function() {
             original += code;
             compressed += result.code;
         });
-        assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
-        assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
+        assert.strictEqual(JSON.stringify(cache).slice(0, 18), '{"vars":{"props":{');
+        assert.strictEqual(compressed, [
+            "function n(n){return 3*n}",
+            "function r(n){return n/2}",
+            "var o=console.log.bind(console);",
+            'function c(n){o("Foo:",2*n)}',
+            "var a=n(3),b=r(12);",
+            'o("qux",a,b),c(11);',
+        ].join(""));
         assert.strictEqual(run_code(compressed), run_code(original));
     });
 
-    it("should not parse invalid use of reserved words", function() {
+    it("Should avoid mangled names in cache", function() {
+        var cache = {};
+        var original = "";
+        var compressed = "";
+        [
+            '"xxxyy";var i={s:1};',
+            '"xxyyy";var j={t:2,u:3},k=4;',
+            'console.log(i.s,j.t,j.u,k);',
+        ].forEach(function(code) {
+            var result = Uglify.minify(code, {
+                compress: false,
+                mangle: {
+                    properties: true,
+                    toplevel: true
+                },
+                nameCache: cache
+            });
+            if (result.error) throw result.error;
+            original += code;
+            compressed += result.code;
+        });
+        assert.strictEqual(compressed, [
+            '"xxxyy";var x={x:1};',
+            '"xxyyy";var y={y:2,a:3},a=4;',
+            'console.log(x.x,y.y,y.a,a);',
+        ].join(""));
+        assert.strictEqual(run_code(compressed), run_code(original));
+    });
+
+    it("Should not parse invalid use of reserved words", function() {
         assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
         assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
         assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");

-- 
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