Remove new Function() calls, and isolate eval() to be used only when necessary. Resolves issue #256.

This commit is contained in:
Davide P. Cervone 2014-03-18 17:19:36 -04:00
parent 6ed8a76d5e
commit f220993196

View File

@ -58,23 +58,13 @@ MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual
var PROTO = []; // a static object used to indicate when a prototype is being created
var OBJECT = function (def) {
var obj = def.constructor; if (!obj) {obj = new Function("")}
var obj = def.constructor; if (!obj) {obj = function () {}}
for (var id in def) {if (id !== 'constructor' && def.hasOwnProperty(id)) {obj[id] = def[id]}}
return obj;
};
var CONSTRUCTOR = function () {
return new Function ("return arguments.callee.Init.call(this,arguments)");
};
//
// Test for Safari 2.x bug (can't replace prototype for result of new Function()).
// (We don't use this version for everyone since it is a closure and we don't need that).
//
var BUGTEST = CONSTRUCTOR(); BUGTEST.prototype = {bug_test: 1};
if (!BUGTEST.prototype.bug_test) {
CONSTRUCTOR = function () {
return function () {return arguments.callee.Init.call(this,arguments)};
};
};
BASE.Object = OBJECT({
constructor: CONSTRUCTOR(),
@ -151,26 +141,17 @@ MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual
},
wrap: function (id,f) {
if (typeof(f) === 'function' && f.toString().match(/\.\s*SUPER\s*\(/)) {
var fn = new Function(this.wrapper);
fn.label = id; fn.original = f; f = fn;
fn.toString = this.stringify;
}
return f;
},
wrapper: function () {
var fn = arguments.callee;
this.SUPER = fn.SUPER[fn.label];
try {var result = fn.original.apply(this,arguments)}
catch (err) {delete this.SUPER; throw err}
if (typeof(f) !== 'function' || !f.toString().match(/\.\s*SUPER\s*\(/)) {return f}
var fn = function () {
this.SUPER = fn.SUPER[id];
try {var result = f.apply(this,arguments)} catch (err) {delete this.SUPER; throw err}
delete this.SUPER;
return result;
}.toString().replace(/^\s*function\s*\(\)\s*\{\s*/i,"").replace(/\s*\}\s*$/i,""),
toString: function () {
return this.original.toString.apply(this.original,arguments);
}
fn.toString = function () {return f.toString.apply(f,arguments)}
return fn;
}
})
});
@ -234,7 +215,7 @@ MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual
// Create a callback from an associative array
//
var CALLBACK = function (data) {
var cb = new Function("return arguments.callee.execute.apply(arguments.callee,arguments)");
var cb = function () {return arguments.callee.execute.apply(arguments.callee,arguments)};
for (var id in CALLBACK.prototype) {
if (CALLBACK.prototype.hasOwnProperty(id)) {
if (typeof(data[id]) !== 'undefined') {cb[id] = data[id]}
@ -261,10 +242,12 @@ MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual
var ISCALLBACK = function (f) {
return (typeof(f) === "function" && f.isCallback);
}
//
// Evaluate a string in global context
//
var EVAL = function (code) {return eval.call(window,code)}
var TESTEVAL = function () {
EVAL("var __TeSt_VaR__ = 1"); // check if it works in global context
if (window.__TeSt_VaR__) {
try { delete window.__TeSt_VaR__; } // NOTE IE9 throws when in IE7 mode
@ -295,6 +278,9 @@ MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual
}
}
}
TESTEVAL = null;
}
//
// Create a callback from various types of data
//
@ -319,6 +305,7 @@ MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual
return CALLBACK({hook: args[1], object: args[0], data: args.slice(2)});
}
} else if (typeof(args) === 'string') {
if (TESTEVAL) TESTEVAL();
return CALLBACK({hook: EVAL, data: [args]});
} else if (args instanceof Object) {
return CALLBACK(args);