Estoy aprendiendo de "Programming in Lua" de Roberto Ierusalimschy, y encontré que en el libro, el ejemplo de Sandboxing usa la función setfenv()
para cambiar el entorno de una función dada, pero en lua 5.2 esto la función ya no está disponible.Sandboxing en Lua 5.2
Intenté cargar algunos valores de un archivo (un archivo de configuración) en un campo de una tabla, pero en lua 5.2 no puedo usar setfenv (para poder cargar los valores en el entorno dado). Después de leer algunos artículos sobre Lua 5.2 me encontré con que cada función puede tener (o no) upvalue llamada _ENV que sirve como el medio ambiente, por lo que, probé el siguiente código:
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
Sustitución _ENV
en la 'caja de arena' la función funciona bien (no puede acceder a los campos regulares), pero cuando se ejecuta el 'código' parece que ignora que reemplacé _ENV
, todavía puede acceder a los campos normales (imprimir, cargar archivo, dofile, etc.).
Leyendo un poco más, encontré que lua 5.2 proporciona una función para este propósito, esta función es loadin(env, chunk)
, que ejecuta el fragmento dado en el entorno dado, pero cuando intento agregar esta función a mi código, la función no existe (no está presente en el campo global _G
).
Alguna ayuda será apreciada.
Gracias! La solución fue fácil. Creo que este enfoque para cambiar el entorno en 'load' y' loadfile' es mejor, porque 'setfenv' se usó principalmente en código cargado así que ... ¡Gracias! Me sandboxed como se esperaba. –
@Miles Cuando se define print_env(), ¿no recibe el _ENV global como un valor ascendente? Entonces, ¿cómo se cambia cuando print_env() se llama dentro de sandbox()? –
@TiagoCosta upvalues son variables locales externas. '_ENV' en este caso es local al fragmento; la asignación a '_ENV' afecta a esa variable local de fragmento, que es un valor de actualización compartido para ambos cierres. – Miles