Skip to content

Commit

Permalink
Ensure we don't reuse an already mangled name from cache
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Sep 13, 2021
1 parent 39548dd commit 5a9d757
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 29 deletions.
3 changes: 3 additions & 0 deletions lib/propmangle.js
Expand Up @@ -214,6 +214,9 @@ function mangle_properties(ast, options) {

var names_to_mangle = new Set();
var unmangleable = new Set();
// Track each already-mangled name to prevent nth_identifier from generating
// the same name.
cache.forEach((mangled_name) => unmangleable.add(mangled_name));

var keep_quoted = !!options.keep_quoted;

Expand Down
70 changes: 41 additions & 29 deletions test/mocha/minify.js
Expand Up @@ -10,9 +10,9 @@ function read(path) {

describe("minify", function() {
it("Should test basic sanity of minify with default options", async function() {
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
var js = "function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }";
var result = await minify(js);
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
assert.strictEqual(result.code, "function foo(n){return n?3:7}");
});

it("Should skip inherited keys from `files`", async function() {
Expand Down Expand Up @@ -128,39 +128,50 @@ describe("minify", function() {
var cache = {};
var original = "";
var compressed = "";
const nth_identifier = {
get(n) {
return String.fromCharCode(n + "a".charCodeAt(0));
}
};

await for_each_async([
'"xxxyy";var i={s:1};',
'"xxyyy";var j={t:2,u:3},k=4;',
"console.log(i.s,j.t,j.u,k);",
'"xxxyy";var i={prop1:1};',
'"xxyyy";var j={prop2:2,prop3:3},k=4;',
"console.log(i.prop1,j.prop2,j.prop3,k);",
"console.log(i.prop2 === undefined, j.prop1 === undefined);",
], async function(code) {
var result = await minify(code, {
compress: false,
mangle: {
properties: true,
toplevel: true
properties: {
nth_identifier,
},
toplevel: true,
},
nameCache: cache
});
original += code;
compressed += result.code;
});
assert.strictEqual(compressed, [
'"xxxyy";var x={s:1};',
'"xxyyy";var y={t:2,u:3},a=4;',
"console.log(x.s,y.t,y.u,a);",
'"xxxyy";var x={g:1};',
'"xxyyy";var p={h:2,i:3},r=4;',
"console.log(x.g,p.h,p.i,r);",
"console.log(x.h===undefined,p.g===undefined);"
].join(""));
assert.strictEqual(run_code(compressed), run_code(original));
});

it("Should consistently rename properties colliding with a mangled name", async function() {
var cache = {};
var original = "";
var compressed = "";

await for_each_async([
"function fn1(obj) { obj.prop = 1; obj.i = 5; }",
"function fn2(obj) { obj.prop = 1; obj.i = 5; }",
"function fn1(obj) { obj.prop = 1; obj.i = 2; }",
"function fn2(obj) { obj.prop = 1; obj.i = 2; }",
"let o1 = {}, o2 = {}; fn1(o1); fn2(o2);",
"console.log(o1.prop === o2.prop, o1.i === o2.i);",
"console.log(o1.prop === o2.prop, o2.prop === 1, o1.i === o2.i, o2.i === 2);",
], async function(code) {
var result = await minify(code, {
compress: false,
Expand All @@ -170,17 +181,18 @@ describe("minify", function() {
},
nameCache: cache
});
original += code;
compressed += result.code;
});
console.log(run_code(compressed));
assert.strictEqual(compressed, [
// It's important that the `n.i` here conflicts with the original's
// `obj.i`, so `obj.i` gets consistently renamed to `n.o`.
"function n(n){n.i=1;n.o=5}",
"function c(n){n.i=1;n.o=5}",
"function n(n){n.i=1;n.o=2}",
"function c(n){n.i=1;n.o=2}",
"let f={},e={};n(f);c(e);",
"console.log(f.i===e.i,f.o===e.o);",
"console.log(f.i===e.i,e.i===1,f.o===e.o,e.o===2);",
].join(""));
assert.equal(run_code(compressed), run_code(original));
});

it("Should not parse invalid use of reserved words", async function() {
Expand Down Expand Up @@ -217,7 +229,7 @@ describe("minify", function() {
keep_quoted_props: false,
quote_style: 3
}});
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
assert.strictEqual(result.code, "var foo={x:1,y:2,z:3};");
});
});

Expand Down Expand Up @@ -268,7 +280,7 @@ describe("minify", function() {

var map = JSON.parse(result.map);

assert.equal(map.file, 'simple.min.js');
assert.equal(map.file, "simple.min.js");
assert.equal(map.sourcesContent.length, 1);
assert.equal(map.sourcesContent[0],
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
Expand Down Expand Up @@ -302,7 +314,7 @@ describe("minify", function() {

describe("sourceMapInline", function() {
it("should append source map to output js when sourceMapInline is enabled", async function() {
var result = await minify('var a = function(foo) { return foo; };', {
var result = await minify("var a = function(foo) { return foo; };", {
sourceMap: {
url: "inline"
}
Expand All @@ -312,7 +324,7 @@ describe("minify", function() {
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
});
it("should not append source map to output js when sourceMapInline is not enabled", async function() {
var result = await minify('var a = function(foo) { return foo; };');
var result = await minify("var a = function(foo) { return foo; };");
var code = result.code;
assert.strictEqual(code, "var a=function(n){return n};");
});
Expand Down Expand Up @@ -421,24 +433,24 @@ describe("minify", function() {
});

it("should work with compress defaults disabled", async function() {
var code = 'if (true) { console.log(1 + 2); }';
var code = "if (true) { console.log(1 + 2); }";
var options = {
compress: {
defaults: false,
}
};
assert.strictEqual((await minify(code, options)).code, 'if(true)console.log(1+2);');
assert.strictEqual((await minify(code, options)).code, "if(true)console.log(1+2);");
});

it("should work with compress defaults disabled and evaluate enabled", async function() {
var code = 'if (true) { console.log(1 + 2); }';
var code = "if (true) { console.log(1 + 2); }";
var options = {
compress: {
defaults: false,
evaluate: true,
}
};
assert.strictEqual((await minify(code, options)).code, 'if(true)console.log(3);');
assert.strictEqual((await minify(code, options)).code, "if(true)console.log(3);");
});

describe("enclose", function() {
Expand All @@ -455,7 +467,7 @@ describe("minify", function() {
it("Should work with arg", async function() {
var result = await minify(code, {
compress: false,
enclose: 'undefined',
enclose: "undefined",
mangle: false,
});
if (result.error) throw result.error;
Expand All @@ -464,7 +476,7 @@ describe("minify", function() {
it("Should work with arg:value", async function() {
var result = await minify(code, {
compress: false,
enclose: 'window,undefined:window',
enclose: "window,undefined:window",
mangle: false,
});
if (result.error) throw result.error;
Expand All @@ -473,9 +485,9 @@ describe("minify", function() {
it("Should work alongside wrap", async function() {
var result = await minify(code, {
compress: false,
enclose: 'window,undefined:window',
enclose: "window,undefined:window",
mangle: false,
wrap: 'exports',
wrap: "exports",
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '(function(window,undefined){(function(exports){function enclose(){console.log("test enclose")}enclose()})(typeof exports=="undefined"?exports={}:exports)})(window);');
Expand Down

0 comments on commit 5a9d757

Please sign in to comment.