Уча се от „Програмиране в Lua“ от Roberto Ierusalimschy и открих, че в книгата примерът за Sandboxing използва функцията setfenv()
за промяна на средата на дадена функция, но в lua 5.2 тази функция вече не е налична.
Опитах се да заредя някои стойности от файл (конфигурационен файл) в поле в таблица, но в lua 5.2 не мога да използвам setfenv (за да мога да заредя стойностите в дадената среда). След като прочетох някои статии за lua 5.2, открих, че всяка функция може да има (или не) повишена стойност, наречена _ENV, която служи като среда, така че опитах следния код:
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
Замяната на _ENV
във функцията „sandbox“ работи добре (няма достъп до обикновените полета), но когато „кодът“ се изпълни, изглежда, че той игнорира, че съм заменил _ENV
, той все още има достъп до обикновените полета (print, loadfile, dofile и т.н.).
Като прочетох малко повече, открих, че lua 5.2 предоставя функция за тази цел, тази функция е loadin(env, chunk)
, която изпълнява даденото парче в дадената среда, но когато се опитам да добавя тази функция към моя код, функцията не съществува (не присъства в глобалното поле _G
).
Малко помощ ще бъде оценена.