From: Alex Lam S.L Date: Fri, 1 Nov 2019 19:34:32 +0000 (+0800) Subject: enhance `unsafe` `evaluate` (#3564) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1c0defdc030debc608e6fa21d8d503d6d6033843;p=UglifyJS.git enhance `unsafe` `evaluate` (#3564) --- diff --git a/lib/compress.js b/lib/compress.js index e3532fef..d8ee2bd3 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2995,6 +2995,7 @@ merge(Compressor.prototype, { ], }; convert_to_predicate(static_values); + var regexp_props = makePredicate("global ignoreCase multiline source"); def(AST_PropAccess, function(compressor, cached, depth) { if (compressor.option("unsafe")) { var key = this.property; @@ -3010,9 +3011,12 @@ merge(Compressor.prototype, { val = global_objs[exp.name]; } else { val = exp._eval(compressor, cached, depth + 1); - if (!val || val === exp) return this; - if (typeof val == "object" && !HOP(val, key)) return this; - if (typeof val == "function") switch (key) { + if (val == null || val === exp) return this; + if (val instanceof RegExp) { + if (!regexp_props[key]) return this; + } else if (typeof val == "object") { + if (!HOP(val, key)) return this; + } else if (typeof val == "function") switch (key) { case "name": return val.node.name ? val.node.name.name : ""; case "length": @@ -3060,7 +3064,7 @@ merge(Compressor.prototype, { val = global_objs[e.name]; } else { val = e._eval(compressor, cached, depth + 1); - if (val === e || !val) return this; + if (val == null || val === e) return this; var native_fn = native_fns[val.constructor.name]; if (!native_fn || !native_fn[key]) return this; } diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 6eadbe51..98d0b8d6 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -237,22 +237,39 @@ unsafe_constant: { unsafe: true, } input: { - console.log( - true.a, - false.a, - null.a, - undefined.a - ); + console.log(true.a, false.a); + console.log(true.valueOf(), false.valueOf()); + try { + console.log(null.a); + } catch (e) { + console.log("PASS"); + } + try { + console.log(undefined.a); + } catch (e) { + console.log("PASS"); + } } expect: { - console.log( - void 0, - false.a, - null.a, - (void 0).a - ); + console.log(void 0, void 0); + console.log(true, false); + try { + console.log(null.a); + } catch (e) { + console.log("PASS"); + } + try { + console.log((void 0).a); + } catch (e) { + console.log("PASS"); + } } - expect_stdout: true + expect_stdout: [ + "undefined undefined", + "true false", + "PASS", + "PASS", + ] } unsafe_object: { diff --git a/test/compress/regexp.js b/test/compress/regexp.js index 6b93faba..460ff504 100644 --- a/test/compress/regexp.js +++ b/test/compress/regexp.js @@ -36,6 +36,20 @@ regexp_2: { expect_stdout: '["PASS","pass"]' } +regexp_properties: { + options = { + evaluate: true, + unsafe: true, + } + input: { + console.log(/abc/g.source, /abc/g.global, /abc/g.ignoreCase, /abc/g.lastIndex, /abc/g.multiline); + } + expect: { + console.log("abc", true, false, /abc/g.lastIndex, false); + } + expect_stdout: "abc true false 0 false" +} + issue_3434_1: { options = { evaluate: true,