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;
});
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){
var exp = this.expression;
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
@@ -1673,9 +1711,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);
}));
}

View File

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