Skip to content

Commit

Permalink
Fix collisions between original property and mangled property
Browse files Browse the repository at this point in the history
This fixes a bug when an original property (`obj.i`) shares the same
name as a mangled property (`obj.prop` -> `n.i`), and you're using a
name-cache. Because our mangled name collides, we have to ensure all
original `.i` properties are renamed to something else (`n.o`).

But, because we had a name-cache, we would reserve the mangled property
name in the mangler. That prevents us from attempting to rename the
original `.i` property to `.o`.
  • Loading branch information
jridgewell committed Sep 3, 2021
1 parent f04077c commit 0605bc3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
3 changes: 0 additions & 3 deletions lib/propmangle.js
Expand Up @@ -167,9 +167,6 @@ function mangle_properties(ast, options) {
var private_cache = new Map();
if (options.cache) {
cache = options.cache.props;
cache.forEach(function(mangled_name) {
reserved.add(mangled_name);
});
} else {
cache = new Map();
}
Expand Down
39 changes: 35 additions & 4 deletions test/mocha/minify.js
Expand Up @@ -124,7 +124,7 @@ describe("minify", function() {
assert.strictEqual(run_code(compressed), run_code(original));
});

it.skip("Should avoid mangled names in cache", async function() {
it("Should avoid mangled names in cache", async function() {
var cache = {};
var original = "";
var compressed = "";
Expand All @@ -145,13 +145,44 @@ describe("minify", function() {
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);',
'"xxxyy";var x={s:1};',
'"xxyyy";var y={t:2,u:3},a=4;',
"console.log(x.s,y.t,y.u,a);",
].join(""));
assert.strictEqual(run_code(compressed), run_code(original));
});

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

await for_each_async([
"function fn1(obj) { obj.prop = 1; obj.i = 5; }",
"function fn2(obj) { obj.prop = 1; obj.i = 5; }",
"let o1 = {}, o2 = {}; fn1(o1); fn2(o2);",
"console.log(o1.prop === o2.prop, o1.i === o2.i);",
], async function(code) {
var result = await minify(code, {
compress: false,
mangle: {
properties: true,
toplevel: true
},
nameCache: cache
});
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}",
"let f={},e={};n(f);c(e);",
"console.log(f.i===e.i,f.o===e.o);",
].join(""));
});

it("Should not parse invalid use of reserved words", async function() {
await assert.doesNotReject(() => minify("function enum(){}"));
await assert.doesNotReject(() => minify("function static(){}"));
Expand Down

0 comments on commit 0605bc3

Please sign in to comment.