whitelist unsafe evaluate candidates (#2039)

- 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:
Alex Lam S.L
2017-06-01 04:33:05 +08:00
committed by GitHub
parent 17e73121fa
commit ec095ed647
2 changed files with 44 additions and 5 deletions

View File

@@ -1665,6 +1665,44 @@ merge(Compressor.prototype, {
} }
throw def; throw def;
}); });
var object_fns = [
'constructor',
'toString',
'valueOf',
];
var native_fns = {
Array: makePredicate([
'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([
'charAt',
'charCodeAt',
'concat',
'indexOf',
'italics',
'lastIndexOf',
'match',
'replace',
'search',
'slice',
'split',
'substr',
'substring',
'trim',
].concat(object_fns)),
};
def(AST_Call, function(compressor){ def(AST_Call, function(compressor){
var exp = this.expression; var exp = this.expression;
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) { if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
@@ -1673,9 +1711,8 @@ merge(Compressor.prototype, {
key = ev(key, compressor); key = ev(key, compressor);
} }
var val = ev(exp.expression, compressor); var val = ev(exp.expression, compressor);
var fn = val[key]; if ((val && native_fns[val.constructor.name] || return_false)(key)) {
if (typeof fn == "function") { return val[key].apply(val, this.args.map(function(arg) {
return fn.apply(val, this.args.map(function(arg) {
return ev(arg, compressor); return ev(arg, compressor);
})); }));
} }

View File

@@ -780,13 +780,15 @@ unsafe_charAt_noop: {
input: { input: {
console.log( console.log(
s.charAt(0), s.charAt(0),
"string".charAt(x) "string".charAt(x),
(typeof x).charAt()
); );
} }
expect: { expect: {
console.log( console.log(
s.charAt(0), s.charAt(0),
"string".charAt(x) "string".charAt(x),
(typeof x)[0]
); );
} }
} }