From 7caab39e261f1787f1a40fca3e7b6fd6ab21d824 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 25 May 2021 23:21:52 +0100 Subject: [PATCH] fix corner case in `mangle` (#4966) fixes #4965 --- README.md | 13 +++++++ lib/scope.js | 17 +-------- test/compress/const.js | 84 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 760fac53f26..06b16551dcb 100644 --- a/README.md +++ b/README.md @@ -1341,3 +1341,16 @@ To allow for better optimizations, the compiler makes various assumptions: // Actual: "FAIL" ``` UglifyJS may modify the input which in turn may suppress those errors. +- Earlier versions of JavaScript will throw `TypeError` with the following: + ```javascript + (function() { + { + const a = "foo"; + } + { + const a = "bar"; + } + })(); + // TypeError: const 'a' has already been declared + ``` + UglifyJS may modify the input which in turn may suppress those errors. diff --git a/lib/scope.js b/lib/scope.js index c74c494ab85..3de59b99c0c 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -87,7 +87,7 @@ SymbolDef.prototype = { var def = scope.variables.get(name) || scope instanceof AST_Toplevel && scope.globals.get(name) || self.orig[0] instanceof AST_SymbolConst && find_if(function(def) { - return def.name == name && def !== self; + return def.name == name; }, scope.enclosed); if (def && def !== self) return def.redefined() || def; }, @@ -123,7 +123,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { // pass 1: setup scope chaining and handle definitions var self = this; - var const_names = null; var defun = null; var exported = false; var next_def_id = 0; @@ -202,7 +201,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } else if (node instanceof AST_SymbolConst) { var def = scope.def_variable(node); def.defun = defun; - const_names.add(def.name, def); if (exported) def.exported = true; } else if (node instanceof AST_SymbolDefun) { var def = defun.def_function(node, tw.parent()); @@ -225,21 +223,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { function walk_scope(descend) { node.init_vars(scope); - var save_names = const_names; var save_defun = defun; var save_scope = scope; - if (node instanceof AST_Scope) { - const_names = new Dictionary(); - defun = node; - } + if (node instanceof AST_Scope) defun = node; scope = node; descend(); - if (node instanceof AST_Scope) const_names.each(function(defs, name) { - if (defs.length > 1 && !node.variables.has(name)) push_uniq(node.enclosed, defs[0]); - }); scope = save_scope; defun = save_defun; - const_names = save_names; } function entangle(defun, scope) { @@ -680,9 +670,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { if (def.scope.parent_scope.find_variable(sym.name)) return false; redef = scope.def_variable(sym); scope.to_mangle.push(redef); - } else if (redef.mangled_name) { - names_in_use(def.scope, options)[redef.mangled_name] = true; - return false; } redefined.push(def); def.references.forEach(reference); diff --git a/test/compress/const.js b/test/compress/const.js index 58c1a3042dc..6a064b41384 100644 --- a/test/compress/const.js +++ b/test/compress/const.js @@ -1539,6 +1539,7 @@ issue_4848: { issue_4954_1: { rename = true input: { + "use strict"; (function() { { const a = "foo"; @@ -1551,18 +1552,23 @@ issue_4954_1: { })(); } expect: { + "use strict"; (function() { { const a = "foo"; console.log(a); } { - const a = "bar"; - console.log(a); + const b = "bar"; + console.log(b); } })(); } - expect_stdout: true + expect_stdout: [ + "foo", + "bar", + ] + node_version: ">=4" } issue_4954_2: { @@ -1610,11 +1616,79 @@ issue_4960: { { const o = console.log("PASS"); } - try {} catch (c) { - const o = console.log("FAIL"); + try {} catch (o) { + const c = console.log("FAIL"); } })(); } expect_stdout: "PASS" node_version: ">=4" } + +issue_4965_1: { + mangle = {} + input: { + "use strict"; + try { + c; + } catch (a) { + { + const a = 1; + } + { + const a = console.log(typeof c); + } + } + } + expect: { + "use strict"; + try { + c; + } catch (t) { + { + const c = 1; + } + { + const t = console.log(typeof c); + } + } + } + expect_stdout: "undefined" + node_version: ">=4" +} + +issue_4965_2: { + mangle = {} + input: { + "use strict"; + try { + throw 1; + } catch (e) { + try { + { + const e = 2; + } + } finally { + const e = 3; + console.log(typeof t); + } + } + } + expect: { + "use strict"; + try { + throw 1; + } catch (o) { + try { + { + const t = 2; + } + } finally { + const o = 3; + console.log(typeof t); + } + } + } + expect_stdout: "undefined" + node_version: ">=4" +}