Sto imparando da "Programmazione in Lua" di Roberto Ierusalimschy, e ho trovato che nel libro, l'esempio di Sandboxing utilizza la funzione setfenv()
per modificare l'ambiente di una determinata funzione, ma in lua 5.2 questo la funzione non è più disponibile.Sandboxing in Lua 5.2
Ho provato a caricare alcuni valori da un file (un file di configurazione) in un campo in una tabella, ma, in lua 5.2 non posso usare setfenv (quindi posso caricare i valori nell'ambiente specificato). Dopo aver letto alcuni articoli su LUA 5.2 ho trovato che ogni funzione può avere (o non) un sopravvalutare chiamato _ENV che serve come l'ambiente, così, ho provato il codice seguente:
function sandbox(sb_func, sb_env)
if not sb_func then return nil, "sandbox function not valid" end
sb_orig_env = _ENV
_ENV = sb_env -- yes, replaces the global _ENV
pcall_res, message = pcall(sb_func)
local modified_env = _ENV -- gets the environment that was used in the pcall(sb_func)
_ENV = sb_orig_env
return true, modified_env
end
function readFile(filename)
code = loadfile(filename)
res, table = sandbox(code, {})
if res then
--[[ Use table (modified_env) ]]--
else
print("Code not valid")
end
Sostituzione _ENV
nel 'sandbox' la funzione funziona bene (non può accedere ai campi regolari), ma, quando viene eseguito il "codice", sembra che ignori che ho sostituito _ENV
, ma può ancora accedere ai campi regolari (stampa, file di caricamento, dofile, ecc.).
Leggendo un po 'di più, ho trovato che lua 5.2 fornisce una funzione per questo scopo, questa funzione è loadin(env, chunk)
, che esegue il blocco dato nell'ambiente specificato, ma, quando provo ad aggiungere questa funzione al mio codice, il la funzione non esiste (non è presente nel campo globale _G
).
Qualche aiuto sarà apprezzato.
Grazie! La soluzione è stata facile. Penso che questo approccio per cambiare l'ambiente in 'load' e' loadfile' sia migliore, perché 'setfenv' è stato usato principalmente nel codice caricato quindi ... Grazie! Ho sandboxed come previsto. –
@Miles Quando print_env() è definito, non riceve il valore globale _ENV come valore? Quindi, come viene modificato quando print_env() viene chiamato all'interno di sandbox()? –
@ Gli upvalues di TiagoCosta sono variabili locali esterne. '_ENV' in questo caso è locale per il blocco; l'assegnazione a '_ENV' influisce sulla variabile locale chunk, che è un valore up condiviso per entrambe le chiusure. – Miles