Uczę się z "Programowania w Lua" przez Roberto Ierusalimschy, i odkryłem, że w książce przykład Sandboxing wykorzystuje funkcję setfenv()
do zmiany środowiska danej funkcji, ale w lua 5.2 to funkcja nie jest już dostępna.Piaskownica w Lua 5.2
Próbowałem załadować niektóre wartości z pliku (pliku konfiguracyjnego) do pola w tabeli, ale w lua 5.2 nie mogę użyć setfenv (aby móc wczytać wartości w danym środowisku). Po przeczytaniu kilku artykułów na temat Lua 5,2 Okazało się, że każda funkcja może mieć (lub nie) jest upvalue nazwie _ENV który służy jako środowisko, tak, próbowałem następujący kod:
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
Wymiana _ENV
w „piaskownicy” funkcja działa dobrze (nie może uzyskać dostępu do zwykłych pól), ale gdy "kod" zostanie wykonany wydaje się, że ignoruje to, że zastąpiłem _ENV
, nadal może uzyskać dostęp do zwykłych pól (print, loadfile, dofile itp.).
Czytając nieco więcej, stwierdziłem, że lua 5.2 udostępnia funkcję do tego celu, ta funkcja to loadin(env, chunk)
, która uruchamia dany fragment w danym środowisku, ale gdy próbuję dodać tę funkcję do mojego kodu, funkcja nie istnieje (nie występuje w globalnym polu _G
).
Pewna pomoc zostanie doceniona.
Dzięki! Rozwiązanie było łatwe. Myślę, że to podejście do zmiany środowiska w 'load' i' loadfile' jest lepsze, ponieważ 'setfenv' był używany głównie w załadowanym kodzie, więc ... Dziękuję! Piaskowałem zgodnie z oczekiwaniami. –
@Miles Kiedy zdefiniowano print_env(), czy nie otrzymuje globalnego _ENV jako upvue? Jak to się zmienia, gdy wywoływana jest funkcja print_env() wewnątrz piaskownicy()? –
@TiagoCosta upvalues są zewnętrznymi zmiennymi lokalnymi. "_ENV" w tym przypadku jest lokalne dla porcji; przypisanie do '_ENV' wpływa na tę zmienną lokalną porcji, która jest wspólną uprawą dla obu zamknięć. – Miles