[Pkg-javascript-commits] [uglifyjs] 39/49: Add --mangle-props-debug and fix --mangle-props=unquoted collision

Jonas Smedegaard dr at jones.dk
Fri Dec 9 11:43:33 UTC 2016


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

js pushed a commit to branch master
in repository uglifyjs.

commit 2a9989dd18c01081c486fe9089e3bb64079c773b
Author: Ashley (Scirra) <ashley at scirra.com>
Date:   Thu Oct 27 11:23:04 2016 -0400

    Add --mangle-props-debug and fix --mangle-props=unquoted collision
    
    Patch by @AshleyScirra
    
    Based on: PR #1316
    
    Renamed the CLI debug option to --mangle-props-debug
    
    Fixes: #1321 name collision in --mangle-props=unquoted
---
 README.md                   | 16 ++++++++
 bin/uglifyjs                |  4 +-
 lib/propmangle.js           | 34 +++++++++++++++--
 test/compress/issue-1321.js | 54 ++++++++++++++++++++++++++
 test/compress/properties.js | 92 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 195 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 789219d..6e9e5f2 100644
--- a/README.md
+++ b/README.md
@@ -285,6 +285,21 @@ of mangled property names.
 Using the name cache is not necessary if you compress all your files in a
 single call to UglifyJS.
 
+#### Debugging property name mangling
+
+You can also pass `--mangle-props-debug` in order to mangle property names
+without completely obscuring them. For example the property `o.foo`
+would mangle to `o._$foo$_` with this option. This allows property mangling
+of a large codebase while still being able to debug the code and identify
+where mangling is breaking things.
+
+You can also pass a custom suffix using `--mangle-props-debug=XYZ`. This would then
+mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a
+script to identify how a property got mangled. One technique is to pass a
+random number on every compile to simulate mangling changing with different
+inputs (e.g. as you update the input script with new properties), and to help
+identify mistakes like writing mangled keys to storage.
+
 ## Compressor options
 
 You need to pass `--compress` (`-c`) to enable the compressor.  Optionally
@@ -749,6 +764,7 @@ Other options:
 
  - `regex` — Pass a RegExp to only mangle certain names (maps to the `--mangle-regex` CLI arguments option)
  - `ignore_quoted` – Only mangle unquoted property names (maps to the `--mangle-props 2` CLI arguments option)
+ - `debug` – Mangle names with the original name still present (maps to the `--mangle-props-debug` CLI arguments option). Defaults to `false`. Pass an empty string to enable, or a non-empty string to set the suffix.
 
 We could add more options to `UglifyJS.minify` — if you need additional
 functionality please suggest!
diff --git a/bin/uglifyjs b/bin/uglifyjs
index ce2e941..d502582 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -98,6 +98,7 @@ You need to pass an argument to this option to specify the name that your module
     .string("beautify")
     .string("m")
     .string("mangle")
+    .string("mangle-props-debug")
     .string("c")
     .string("compress")
     .string("d")
@@ -419,7 +420,8 @@ async.eachLimit(files, 1, function (file, cb) {
             cache         : cache,
             only_cache    : !ARGS.mangle_props,
             regex         : regex,
-            ignore_quoted : ARGS.mangle_props == 2
+            ignore_quoted : ARGS.mangle_props == 2,
+            debug         : typeof ARGS.mangle_props_debug === "undefined" ? false : ARGS.mangle_props_debug
         });
         writeNameCache("props", cache);
     })();
diff --git a/lib/propmangle.js b/lib/propmangle.js
index 3923baa..f277747 100644
--- a/lib/propmangle.js
+++ b/lib/propmangle.js
@@ -66,7 +66,8 @@ function mangle_properties(ast, options) {
         cache : null,
         only_cache : false,
         regex : null,
-        ignore_quoted : false
+        ignore_quoted : false,
+        debug : false
     });
 
     var reserved = options.reserved;
@@ -84,6 +85,15 @@ function mangle_properties(ast, options) {
     var regex = options.regex;
     var ignore_quoted = options.ignore_quoted;
 
+    // note debug is either false (disabled), or a string of the debug suffix to use (enabled).
+    // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
+    // the same as passing an empty string.
+    var debug = (options.debug !== false);
+    var debug_name_suffix;
+    if (debug) {
+        debug_name_suffix = (options.debug === true ? "" : options.debug);
+    }
+
     var names_to_mangle = [];
     var unmangleable = [];
     var ignored = {};
@@ -177,9 +187,25 @@ function mangle_properties(ast, options) {
 
         var mangled = cache.props.get(name);
         if (!mangled) {
-            do {
-                mangled = base54(++cache.cname);
-            } while (!can_mangle(mangled));
+            if (debug) {
+                // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
+                var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
+
+                if (can_mangle(debug_mangled) && !(ignore_quoted && debug_mangled in ignored)) {
+                    mangled = debug_mangled;
+                }
+            }
+
+            // either debug mode is off, or it is on and we could not use the mangled name
+            if (!mangled) {
+                // note can_mangle() does not check if the name collides with the 'ignored' set
+                // (filled with quoted properties when ignore_quoted set). Make sure we add this
+                // check so we don't collide with a quoted name.
+                do {
+                    mangled = base54(++cache.cname);
+                } while (!can_mangle(mangled) || (ignore_quoted && mangled in ignored));
+            }
+
             cache.props.set(name, mangled);
         }
         return mangled;
diff --git a/test/compress/issue-1321.js b/test/compress/issue-1321.js
new file mode 100644
index 0000000..2b6f17b
--- /dev/null
+++ b/test/compress/issue-1321.js
@@ -0,0 +1,54 @@
+issue_1321_no_debug: {
+    mangle_props = {
+        ignore_quoted: true
+    }
+    input: {
+        var x = {};
+        x.foo = 1;
+        x["a"] = 2 * x.foo;
+        console.log(x.foo, x["a"]);
+    }
+    expect: {
+        var x = {};
+        x.b = 1;
+        x["a"] = 2 * x.b;
+        console.log(x.b, x["a"]);
+    }
+}
+
+issue_1321_debug: {
+    mangle_props = {
+        ignore_quoted: true,
+        debug: ""
+    }
+    input: {
+        var x = {};
+        x.foo = 1;
+        x["_$foo$_"] = 2 * x.foo;
+        console.log(x.foo, x["_$foo$_"]);
+    }
+    expect: {
+        var x = {};
+        x.a = 1;
+        x["_$foo$_"] = 2 * x.a;
+        console.log(x.a, x["_$foo$_"]);
+    }
+}
+
+issue_1321_with_quoted: {
+    mangle_props = {
+        ignore_quoted: false
+    }
+    input: {
+        var x = {};
+        x.foo = 1;
+        x["a"] = 2 * x.foo;
+        console.log(x.foo, x["a"]);
+    }
+    expect: {
+        var x = {};
+        x.a = 1;
+        x["b"] = 2 * x.a;
+        console.log(x.a, x["b"]);
+    }
+}
diff --git a/test/compress/properties.js b/test/compress/properties.js
index f168080..22f2c33 100644
--- a/test/compress/properties.js
+++ b/test/compress/properties.js
@@ -142,6 +142,98 @@ mangle_unquoted_properties: {
     }
 }
 
+mangle_debug: {
+    mangle_props = {
+        debug: ""
+    };
+    input: {
+        a.foo = "bar";
+        x = { baz: "ban" };
+    }
+    expect: {
+        a._$foo$_ = "bar";
+        x = { _$baz$_: "ban" };
+    }
+}
+
+mangle_debug_true: {
+    mangle_props = {
+        debug: true
+    };
+    input: {
+        a.foo = "bar";
+        x = { baz: "ban" };
+    }
+    expect: {
+        a._$foo$_ = "bar";
+        x = { _$baz$_: "ban" };
+    }
+}
+
+mangle_debug_suffix: {
+    mangle_props = {
+        debug: "XYZ"
+    };
+    input: {
+        a.foo = "bar";
+        x = { baz: "ban" };
+    }
+    expect: {
+        a._$foo$XYZ_ = "bar";
+        x = { _$baz$XYZ_: "ban" };
+    }
+}
+
+mangle_debug_suffix_ignore_quoted: {
+    options = {
+        properties: false
+    }
+    mangle_props = {
+        ignore_quoted: true,
+        debug: "XYZ",
+        reserved: []
+    }
+    beautify = {
+        beautify: false,
+        quote_style: 3,
+        keep_quoted_props: true,
+    }
+    input: {
+        a.top = 1;
+        function f1() {
+            a["foo"] = "bar";
+            a.color = "red";
+            a.stuff = 2;
+            x = {"bar": 10, size: 7};
+            a.size = 9;
+        }
+        function f2() {
+            a.foo = "bar";
+            a['color'] = "red";
+            x = {bar: 10, size: 7};
+            a.size = 9;
+            a.stuff = 3;
+        }
+    }
+    expect: {
+        a._$top$XYZ_ = 1;
+        function f1() {
+            a["foo"] = "bar";
+            a.color = "red";
+            a._$stuff$XYZ_ = 2;
+            x = {"bar": 10, _$size$XYZ_: 7};
+            a._$size$XYZ_ = 9;
+        }
+        function f2() {
+            a.foo = "bar";
+            a['color'] = "red";
+            x = {bar: 10, _$size$XYZ_: 7};
+            a._$size$XYZ_ = 9;
+            a._$stuff$XYZ_ = 3;
+        }
+    }
+}
+
 first_256_chars_as_properties: {
     beautify = {
         ascii_only: true,

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