From c3890faeac66d3fbb35d7692ac1775c195514777 Mon Sep 17 00:00:00 2001 From: FelisCatus Date: Tue, 5 Aug 2014 17:58:54 +0800 Subject: [PATCH] Add support for CSP context without "unsafe-eval". --- lib/ast.js | 28 +++++++++++++------ lib/mozilla-ast.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++ lib/utils.js | 5 ++++ 3 files changed, 95 insertions(+), 8 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 051cd2fb..3570caa4 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -50,15 +50,27 @@ function DEFNODE(type, props, methods, base) { var self_props = props; if (base && base.PROPS) props = props.concat(base.PROPS); - var code = "return function AST_" + type + "(props){ if (props) { "; - for (var i = props.length; --i >= 0;) { - code += "this." + props[i] + " = props." + props[i] + ";"; - } var proto = base && new base; - if (proto && proto.initialize || (methods && methods.initialize)) - code += "this.initialize();"; - code += "}}"; - var ctor = new Function(code)(); + var ctor; + if (typeof UglifyJS_NoUnsafeEval === "undefined") { + var code = "return function AST_" + type + "(props){ if (props) { "; + for (var i = props.length; --i >= 0;) { + code += "this." + props[i] + " = props." + props[i] + ";"; + } + if (proto && proto.initialize || (methods && methods.initialize)) + code += "this.initialize();"; + code += "}}"; + ctor = new Function(code)(); + } else { + ctor = function (values) { + if (values) { + for (var i = props.length; --i >= 0; ) + this[props[i]] = values[props[i]]; + if (proto && proto.initialize || (methods && methods.initialize)) + this.initialize(); + } + }; + } if (proto) { ctor.prototype = proto; ctor.BASE = base; diff --git a/lib/mozilla-ast.js b/lib/mozilla-ast.js index 602ef0e6..bf519617 100644 --- a/lib/mozilla-ast.js +++ b/lib/mozilla-ast.js @@ -394,6 +394,76 @@ }; function map(moztype, mytype, propmap) { + if (typeof UglifyJS_NoUnsafeEval !== "undefined") { + var prop_list = []; + if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) { + var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop); + if (!m) throw new Error("Can't understand property map: " + prop); + if ('=@>%'.indexOf(m[2]) < 0) { + throw new Error("Can't understand operator in propmap: " + prop); + } + prop_list.push(m); + }); + var moz_to_me = function (M) { + var props = { + start: my_start_token(M), + end: my_end_token(M) + }; + for (var i = 0; i < prop_list.length; i++) { + var m = prop_list[i]; + var moz = m[1], how = m[2], my = m[3]; + var mozProp = M[moz]; + var myProp; + switch (how) { + case "@": + myProp = mozProp.map(from_moz); + break; + case ">": + myProp = from_moz(mozProp); + break; + case "=": + myProp = mozProp; + break; + case "%": + myProp = from_moz(mozProp).body; + break; + } + props[my] = myProp; + } + return new mytype(props); + }; + var me_to_moz = function (M) { + var props = { + type: moztype + }; + for (var i = 0; i < prop_list.length; i++) { + var m = prop_list[i]; + var moz = m[1], how = m[2], my = m[3]; + var myProp = M[my]; + var mozProp; + switch (how) { + case "@": + mozProp = myProp.map(to_moz); + break; + case ">": + mozProp = to_moz(myProp); + break; + case "=": + mozProp = myProp; + break; + case "%": + mozProp = to_moz_block(M); + break; + } + props[moz] = mozProp; + } + return props; + }; + MOZ_TO_ME[moztype] = moz_to_me; + def_to_moz(mytype, me_to_moz); + return; + } + var moz_to_me = "function From_Moz_" + moztype + "(M){\n"; moz_to_me += "return new " + mytype.name + "({\n" + "start: my_start_token(M),\n" + diff --git a/lib/utils.js b/lib/utils.js index 7c6a1563..e69d7073 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -219,6 +219,11 @@ function set_intersection(a, b) { // [1] https://github.com/marijnh/acorn function makePredicate(words) { if (!(words instanceof Array)) words = words.split(" "); + if (typeof UglifyJS_NoUnsafeEval !== "undefined") { + return function (str) { + return words.indexOf(str) >= 0; + }; + } var f = "", cats = []; out: for (var i = 0; i < words.length; ++i) { for (var j = 0; j < cats.length; ++j)