注:這是仍在工作進步,部分受到斜視代碼片段的啓發。
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極光瀏覽網頁的網址,但並非對鉻也沒有對暫存器devtool - Firefox的__noSuchMethod__
或類似的「後期綁定」機制的可能是手工,導致性訪問,只有當被添加)。
你想沙箱'eval''d /任意代碼?如果這是你的目標,有更好的方法。 –
不,我只是想從用戶代碼屏蔽全局範圍。這使我想到了這個問題,這是關於理論的。 – kol
然後,在現代瀏覽器中,理論上你可以[凍結](window)對象(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)。雖然我從來沒有嘗試過。 –