ad un certo punto devi avere fiducia in ciò che è disponibile sulla finestra. Ciò significa memorizzare nella cache le funzioni che si sta pianificando di utilizzare o tentare di eseguire la sandbox del codice.
La soluzione "semplice" a chiamare call
è quello di impostare temporaneamente una proprietà:
var safeCall = (function (call, id) {
return function (fn, ctx) {
var ret,
args,
i;
args = [];
// The temptation is great to use Array.prototype.slice.call here
// but we can't rely on call being available
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
// set the call function on the call function so that it can be...called
call[id] = call;
// call call
ret = call[id](fn, ctx, args);
// unset the call function from the call function
delete call[id];
return ret;
};
}(Function.prototype.call, (''+Math.random()).slice(2)));
Questo può quindi essere utilizzato come:
safeCall(fn, ctx, ...params);
essere consapevoli del fatto che i parametri passati al safecall saranno raggruppati in un array. Avresti bisogno di apply
per farlo funzionare correttamente, e sto solo cercando di semplificare le dipendenze qui.
versione migliorata del safeCall
aggiungere una dipendenza per apply
:
var safeCall = (function (call, apply, id) {
return function (fn, ctx) {
var ret,
args,
i;
args = [];
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
apply[id] = call;
ret = apply[id](fn, ctx, args);
delete apply[id];
return ret;
};
}(Function.prototype.call, Function.prototype.apply, (''+Math.random()).slice(2)));
Questo può essere usato come:
safeCall(fn, ctx, ...params);
Una soluzione alternativa a chiamare in modo sicuro invito è quello di utilizzare funziona da un contesto di finestra differente.
questo può essere fatto semplicemente creando un nuovo iframe
e afferrando le funzioni dalla sua finestra. Avrai ancora bisogno di assumere una certa quantità di dipendenza da funzioni di manipolazione DOM di essere disponibile, ma che accade come un passo di installazione, in modo che eventuali modifiche non influiranno sul script esistente:
var sandboxCall = (function() {
var sandbox,
call;
// create a sandbox to play in
sandbox = document.createElement('iframe');
sandbox.src = 'about:blank';
document.body.appendChild(sandbox);
// grab the function you need from the sandbox
call = sandbox.contentWindow.Function.prototype.call;
// dump the sandbox
document.body.removeChild(sandbox);
return call;
}());
Questo può quindi essere Usato come:
sandboxCall.call(fn, ctx, ...params);
Sia safeCall
e sandboxCall
sono al sicuro da futuro modifiche Function.prototype.call
, ma come si c un punto di vista si basano su alcune funzioni globali esistenti per funzionare in fase di runtime. Se uno script dannoso esegue prima del codice, il codice sarà ancora vulnerabile.
Mi ha portato 3 letture ... ma bella domanda! –