注:これは仕事にまだありますスケートのコードスニペットに部分的に触発されています。 (Firefoxのスクラッチパッドから)
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
};
}
出力結果:
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を返しますが、chromeやscratchpad devtoolでは表示されません - おそらくFirefoxの__noSuchMethod__
や同様の 'late-binding'メカニズムの手作業によってアクセスされたときにのみプロパティが追加されます)。
'eval''d /任意のコードをサンドボックスしようとしていますか?それがあなたの目的なら、より良い方法があります。 –
いいえ、私はちょうどユーザーコードからグローバルスコープを遮蔽することを考えていました。これは私にこの質問につながりました。理論についてです。 – kol
それから、現代のブラウザでは、理論的に、 'window'オブジェクトを(フリーズして)(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)できます。私はそれを試みたことはありませんが。 –