I am learning from "Programing in Lua" by Roberto Ierusalimschy, and I found that in the book, the example of Sandboxing uses the function setfenv()
to change the environment of a given function, but in lua 5.2 this function is no longer available.
I tried to load some values from a file (a configuration file) into a field in a table, but, in lua 5.2 I can't use setfenv ( so I can load the values in the given environment). After reading some articles about lua 5.2 I found that each function may have (or not) an upvalue called _ENV which serves as the environment, so, I tried the following code:
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
Replacing _ENV
in the 'sandbox' function works well (can't access the regular fields), but, when the 'code' is executed it seems that it ignores that I replaced _ENV
, it still can access regular fields (print, loadfile, dofile, etc).
Reading a little more, I found that lua 5.2 provides a function for this purpose, this function is loadin(env, chunk)
, which runs the given chunk in the given environment, but, when I try to add this function to my code, the function doesn't exist ( Is not present in the global _G
field).
Some help will be appreciated.
load
andloadfile
is better, becausesetfenv
was used mostly in loaded code so... Thank you! I sandboxed as expected. – Peggiepeggir