From: Alex Lam S.L Date: Wed, 31 May 2017 20:33:05 +0000 (+0800) Subject: whitelist `unsafe` `evaluate` candidates (#2039) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=ec095ed647691b3458ec9e65e89ff92d5151abc4;p=UglifyJS.git 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 --- diff --git a/lib/compress.js b/lib/compress.js index a928d7b7..71cffcee 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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); })); } diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 020d7cf3..99245d0d 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -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] ); } }