From 30cfea2e7a95fd5aaa8092ea0b305ef0be760534 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 24 Nov 2017 03:05:43 +0800 Subject: [PATCH] fix `rename` (#2501) - suppress spurious `rename` from `commander` - handle `AST_SymbolCatch` correctly --- bin/uglifyjs | 1 + lib/scope.js | 9 +- test/compress/rename.js | 536 ++++++++++++++++++++++++++++++++++++++++ test/run-tests.js | 4 + 4 files changed, 547 insertions(+), 3 deletions(-) create mode 100644 test/compress/rename.js diff --git a/bin/uglifyjs b/bin/uglifyjs index 661f7260..718397c1 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -72,6 +72,7 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { "wrap" ].forEach(function(name) { if (name in program) { + if (name == "rename" && program[name]) return; options[name] = program[name]; } }); diff --git a/lib/scope.js b/lib/scope.js index ea35c0bf..f3010e7c 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -456,6 +456,7 @@ AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) { this.globals.each(add_def); this.walk(new TreeWalker(function(node) { if (node instanceof AST_Scope) node.variables.each(add_def); + if (node instanceof AST_SymbolCatch) add_def(node.definition()); })); var prefix, i = 0; do { @@ -492,17 +493,19 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) { this.globals.each(rename); this.walk(new TreeWalker(function(node) { if (node instanceof AST_Scope) node.variables.each(rename); + if (node instanceof AST_SymbolCatch) rename(node.definition()); })); function rename(def) { if (def.global || def.unmangleable(options)) return; if (member(def.name, options.reserved)) return; - var name = prefix + def.id; + var d = def.redefined(); + def.name = d ? d.name : prefix + def.id; def.orig.forEach(function(sym) { - sym.name = name; + sym.name = def.name; }); def.references.forEach(function(sym) { - sym.name = name; + sym.name = def.name; }); } }); diff --git a/test/compress/rename.js b/test/compress/rename.js new file mode 100644 index 00000000..defc6cf5 --- /dev/null +++ b/test/compress/rename.js @@ -0,0 +1,536 @@ +mangle_catch: { + rename = true + options = { + ie8: false, + toplevel: false, + } + mangle = { + ie8: false, + toplevel: false, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + a = "PASS"; + } + console.log(a); + } + expect_exact: 'var a="FAIL";try{throw 1}catch(o){a="PASS"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_ie8: { + rename = true + options = { + ie8: true, + toplevel: false, + } + mangle = { + ie8: true, + toplevel: false, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + a = "PASS"; + } + console.log(a); + } + expect_exact: 'var a="FAIL";try{throw 1}catch(args){a="PASS"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_var: { + rename = true + options = { + ie8: false, + toplevel: false, + } + mangle = { + ie8: false, + toplevel: false, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + var a = "PASS"; + } + console.log(a); + } + expect_exact: 'var a="FAIL";try{throw 1}catch(o){var a="PASS"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_var_ie8: { + rename = true + options = { + ie8: true, + toplevel: false, + } + mangle = { + ie8: true, + toplevel: false, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + var a = "PASS"; + } + console.log(a); + } + expect_exact: 'var a="FAIL";try{throw 1}catch(args){var a="PASS"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_toplevel: { + rename = true + options = { + ie8: false, + toplevel: true, + } + mangle = { + ie8: false, + toplevel: true, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + a = "PASS"; + } + console.log(a); + } + expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_ie8_toplevel: { + rename = true + options = { + ie8: true, + toplevel: true, + } + mangle = { + ie8: true, + toplevel: true, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + a = "PASS"; + } + console.log(a); + } + expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_var_toplevel: { + rename = true + options = { + ie8: false, + toplevel: true, + } + mangle = { + ie8: false, + toplevel: true, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + var a = "PASS"; + } + console.log(a); + } + expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_var_ie8_toplevel: { + rename = true + options = { + ie8: true, + toplevel: true, + } + mangle = { + ie8: true, + toplevel: true, + } + input: { + var a = "FAIL"; + try { + throw 1; + } catch (args) { + var a = "PASS"; + } + console.log(a); + } + expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1: { + rename = true + options = { + ie8: false, + toplevel: false, + } + mangle = { + ie8: false, + toplevel: false, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1_ie8: { + rename = true + options = { + ie8: true, + toplevel: false, + } + mangle = { + ie8: true, + toplevel: false, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1_toplevel: { + rename = true + options = { + ie8: false, + toplevel: true, + } + mangle = { + ie8: false, + toplevel: true, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_redef_1_ie8_toplevel: { + rename = true + options = { + ie8: true, + toplevel: true, + } + mangle = { + ie8: true, + toplevel: true, + } + input: { + var a = "PASS"; + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "PASS" +} + +mangle_catch_redef_2: { + rename = true + options = { + ie8: false, + toplevel: false, + } + mangle = { + ie8: false, + toplevel: false, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "undefined" +} + +mangle_catch_redef_2_ie8: { + rename = true + options = { + ie8: true, + toplevel: false, + } + mangle = { + ie8: true, + toplevel: false, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);' + expect_stdout: "undefined" +} + +mangle_catch_redef_2_toplevel: { + rename = true + options = { + ie8: false, + toplevel: true, + } + mangle = { + ie8: false, + toplevel: true, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "undefined" +} + +mangle_catch_redef_2_ie8_toplevel: { + rename = true + options = { + ie8: true, + toplevel: true, + } + mangle = { + ie8: true, + toplevel: true, + } + input: { + try { + throw "FAIL1"; + } catch (a) { + var a = "FAIL2"; + } + console.log(a); + } + expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);' + expect_stdout: "undefined" +} + +issue_2120_1: { + rename = true + mangle = { + ie8: false, + } + input: { + "aaaaaaaa"; + var a = 1, b = "FAIL"; + try { + throw 1; + } catch (c) { + try { + throw 0; + } catch (a) { + if (c) b = "PASS"; + } + } + console.log(b); + } + expect: { + "aaaaaaaa"; + var a = 1, b = "FAIL"; + try { + throw 1; + } catch (t) { + try { + throw 0; + } catch (a) { + if (t) b = "PASS"; + } + } + console.log(b); + } + expect_stdout: "PASS" +} + +issue_2120_2: { + rename = true + mangle = { + ie8: true, + } + input: { + "aaaaaaaa"; + var a = 1, b = "FAIL"; + try { + throw 1; + } catch (c) { + try { + throw 0; + } catch (a) { + if (c) b = "PASS"; + } + } + console.log(b); + } + expect: { + "aaaaaaaa"; + var a = 1, b = "FAIL"; + try { + throw 1; + } catch (c) { + try { + throw 0; + } catch (a) { + if (c) b = "PASS"; + } + } + console.log(b); + } + expect_stdout: "PASS" +} +function_iife_catch: { + rename = true + mangle = { + ie8: false, + } + input: { + function f(n) { + !function() { + try { + throw 0; + } catch (n) { + var a = 1; + console.log(n, a); + } + }(); + } + f(); + } + expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();" + expect_stdout: "0 1" +} + +function_iife_catch_ie8: { + rename = true + mangle = { + ie8: true, + } + input: { + function f(n) { + !function() { + try { + throw 0; + } catch (n) { + var a = 1; + console.log(n, a); + } + }(); + } + f(); + } + expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();" + expect_stdout: "0 1" +} + +function_catch_catch: { + rename = true + mangle = { + ie8: false, + } + input: { + var o = 0; + function f() { + try { + throw 1; + } catch (c) { + try { + throw 2; + } catch (o) { + var o = 3; + console.log(o); + } + } + console.log(o); + } + f(); + } + expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();" + expect_stdout: [ + "3", + "undefined", + ] +} + +function_catch_catch_ie8: { + rename = true + mangle = { + ie8: true, + } + input: { + var o = 0; + function f() { + try { + throw 1; + } catch (c) { + try { + throw 2; + } catch (o) { + var o = 3; + console.log(o); + } + } + console.log(o); + } + f(); + } + expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();" + expect_stdout: [ + "3", + "undefined", + ] +} diff --git a/test/run-tests.js b/test/run-tests.js index 0051c6c2..e95bbb83 100755 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -117,6 +117,10 @@ function run_compress_tests() { test.mangle.properties.reserved = quoted_props; U.reserve_quoted_keys(input, quoted_props); } + if (test.rename) { + input.figure_out_scope(test.mangle); + input.expand_names(test.mangle); + } var cmp = new U.Compressor(options, true); var output = cmp.compress(input); output.figure_out_scope(test.mangle); -- 2.34.1