I want to execute an untrusted .lua file in its own environment by calling lua_setfenv() so that it cannot affect any of my code.
The documentation for that function tho
By the way, this is what I ended up doing:
/* Loads, compiles and executes an unstrusted file. */
bool Lua::RunUntrustedFile(const string& path)
{
if(luaL_loadfile(mState, path.c_str()))
{
ErrorLog(lua_tostring(mState, 1));
Pop(1);
return false;
}
Lua::SetMaximumInstructions(100000000);
lua_newtable(mState);
lua_setglobal(mState, "upload");
ASSERT(Lua::GetStackSize() == 1);
lua_getglobal(mState, "upload");
ASSERT_ALWAYS(lua_setfenv(mState, 1) != 0);
ASSERT(Lua::GetStackSize() == 1);
if(lua_pcall(mState, 0, 0, 0))
{
Lua::ClearMaximumInstructions();
ErrorLog(lua_tostring(mState, -1));
Pop(1);
return false;
}
ASSERT(Lua::GetStackSize() == 0);
Lua::ClearMaximumInstructions();
return true;
}
"Support" functions:
static void Pop(int elements = 1) { lua_pop(mState, elements); }
/* Sets a maximum number of instructions before throwing an error */
static void SetMaximumInstructions(int count) {
lua_sethook(mState, &Lua::MaximumInstructionsReached, LUA_MASKCOUNT, count);
}
static void ClearMaximumInstructions() {
lua_sethook(mState, &Lua::MaximumInstructionsReached, 0, 0);
}
static void MaximumInstructionsReached(lua_State *, lua_Debug *)
{
Error("The maximum number of instructions has been reached");
}
static int GetStackSize() { return lua_gettop(mState); }