avoid mutating options

The `defaults()` function is changed, so that `defs` is mutated and
returned instead of `args`. This change does not cause issues, since
`defaults()` is always called with `defs` as an object literal.

fixes #2595
This commit is contained in:
Dan Wolff 2018-02-06 22:43:05 +01:00
parent dea0cc0662
commit 948c647d3f
4 changed files with 41 additions and 10 deletions

View File

@ -120,7 +120,7 @@ function minify(files, options) {
if (typeof files == "string") {
files = [ files ];
}
options.parse = options.parse || {};
options.parse = assign({}, options.parse);
options.parse.toplevel = null;
for (var name in files) if (HOP(files, name)) {
options.parse.filename = name;
@ -159,6 +159,7 @@ function minify(files, options) {
toplevel = mangle_properties(toplevel, options.mangle.properties);
}
if (timings) timings.output = Date.now();
options.output = assign({}, options.output);
var result = {};
if (options.output.ast) {
result.ast = toplevel;

View File

@ -405,7 +405,7 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
reserved : [],
toplevel : false,
});
if (!Array.isArray(options.reserved)) options.reserved = [];
options.reserved = Array.isArray(options.reserved) ? options.reserved.slice() : [];
// Never mangle arguments
push_uniq(options.reserved, "arguments");
return options;

View File

@ -95,15 +95,14 @@ DefaultsError.croak = function(msg, defs) {
};
function defaults(args, defs, croak) {
if (args === true)
args = {};
var ret = args || {};
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
DefaultsError.croak("`" + i + "` is not a supported option", defs);
for (var i in defs) if (HOP(defs, i)) {
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
if (args === true || !args) return defs;
for (var i in args) if (HOP(args, i)) {
if (croak && !HOP(defs, i))
DefaultsError.croak("`" + i + "` is not a supported option", defs);
defs[i] = args[i];
}
return ret;
return defs;
};
function merge(obj, ext) {
@ -115,6 +114,11 @@ function merge(obj, ext) {
return count;
};
function assign(obj, ext) {
merge(obj, ext);
return obj;
};
function noop() {}
function return_false() { return false; }
function return_true() { return true; }

View File

@ -122,6 +122,32 @@ describe("minify", function() {
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
});
it("Should not mutate options", function() {
[
{},
{
parse: {},
compress: {
global_defs: {},
},
mangle: {
reserved: [],
// expect `cache` to be mutated
},
output: {},
rename: {
reserved: [],
},
sourceMap: {},
// expect `nameCache` to be mutated
},
].forEach(function(options) {
var optsString = JSON.stringify(options);
Uglify.minify("", options);
assert.strictEqual(JSON.stringify(options), optsString);
});
});
describe("keep_quoted_props", function() {
it("Should preserve quotes in object literals", function() {
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';