whitelist unsafe evaluate candidates

- all arguments may accept constant values
- return constant value
- free of side effects
- available & identical across locales and runtime environments
This commit is contained in:
alexlamsl 2017-06-01 02:36:37 +08:00
parent 17e73121fa
commit f70aaebc5b

View File

@ -1665,6 +1665,61 @@ merge(Compressor.prototype, {
}
throw def;
});
var object_fns = [
'constructor',
'toLocaleString',
'toString',
'valueOf',
];
var native_fns = {
Array: makePredicate([
'concat',
'indexOf',
'join',
'lastIndexOf',
'slice',
].concat(object_fns)),
Boolean: makePredicate(object_fns),
Number: makePredicate([
'toExponential',
'toFixed',
'toPrecision',
].concat(object_fns)),
RegExp: makePredicate([
'test',
].concat(object_fns)),
String: makePredicate([
'anchor',
'big',
'blink',
'bold',
'charAt',
'charCodeAt',
'concat',
'fixed',
'fontcolor',
'fontsize',
'indexOf',
'italics',
'lastIndexOf',
'link',
'localeCompare',
'match',
'replace',
'search',
'slice',
'small',
'split',
'strike',
'sub',
'substr',
'substring',
'sup',
'toLocaleLowerCase',
'toLocaleUpperCase',
'trim',
].concat(object_fns)),
};
def(AST_Call, function(compressor){
var exp = this.expression;
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
@ -1673,9 +1728,8 @@ merge(Compressor.prototype, {
key = ev(key, compressor);
}
var val = ev(exp.expression, compressor);
var fn = val[key];
if (typeof fn == "function") {
return fn.apply(val, this.args.map(function(arg) {
if ((val && native_fns[val.constructor.name] || return_false)(key)) {
return val[key].apply(val, this.args.map(function(arg) {
return ev(arg, compressor);
}));
}