注: これはまだ進行中の作業であり、一部は squint のコード スニペットに触発されています。
function quarantinedFunction(fnText){
var exceptionKeys=[
"eval","Object", //need exceptions for this else error. (ie, 'Exception: redefining eval is deprecated')
"Number","String","Boolean","RegExp","JSON","Date",
];
var forbiddenKeys=[
"fn","fnText","forbiddenKeys","exceptionKeys","empty","oForbiddenKeys",
];
var oForbiddenKeys=Object.create(null);
var empty=Object.create(null);
Object.freeze(empty);
forbiddenKeys.forEach(function(key){
oForbiddenKeys[key]=null;
});
[this,self].forEach(function(obj){
Object.getOwnPropertyNames(obj).forEach(function(key){
if(!key.match(/^[\$\w]+$/))return;
oForbiddenKeys[key]=null;
});
});
exceptionKeys.forEach(function(key){
delete oForbiddenKeys[key];
});
if(0){//debugging.
return function(){
return Object.keys(oForbiddenKeys);
return Object.keys(empty);
};
}
fnText=[
'"use strict";',
"var "+Object.keys(oForbiddenKeys).join(", ")+";",
"{",
fnText,
"}"
].join("\n");
var fn= (function(){
with(empty)
{
return new Function("self","window",fnText);
}
})();
return function(){
return fn.call(Object.create(null)); //self,window undefined
return fn.call(empty,empty,empty); //self,window are objects w/o properties
};
}
出力結果 (Firefox スクラッチパッドから):
quarantinedFunction("return location.href;")();
/*
Exception: location is undefined
*/
quarantinedFunction("someGlobalVar=15;")();
/*
Exception: assignment to undeclared variable someGlobalVar
*/
quarantinedFunction("return 9*9;")();
/*
81
*/
quarantinedFunction("return console;")();
/*
undefined
*/
そして、いくつかの結果を持つjsfiddle。
注: いくつかの予期しない結果がフィドルに表示されますが、他のツールには表示されません (つまり、location
変数は、フィドルが Firefox オーロラから表示されたときにページの URL を返しますが、クロムやスクラッチパッド devtool では表示されません。おそらく Firefox__noSuchMethod__
または類似のものの手仕事によるものです)。アクセスされたときにのみプロパティが追加される「遅延バインディング」メカニズム)。