From af9c3d7de7e35632d046575b5e4809a04abec816 Mon Sep 17 00:00:00 2001 From: aunsane Date: Thu, 28 Sep 2017 20:16:27 +0300 Subject: MirLua: added CMLuaEnviroment to execute lua code from extetnal source in sandbox --- plugins/MirLua/src/m_core.cpp | 54 +++++++++++++------------- plugins/MirLua/src/m_genmenu.cpp | 2 +- plugins/MirLua/src/m_hotkeys.cpp | 2 +- plugins/MirLua/src/m_icolib.cpp | 7 ++-- plugins/MirLua/src/m_options.cpp | 2 +- plugins/MirLua/src/m_sounds.cpp | 2 +- plugins/MirLua/src/m_srmm.cpp | 2 +- plugins/MirLua/src/mlua_enviroment.cpp | 71 ++++++++++++++++++++++++++++++++++ plugins/MirLua/src/mlua_enviroment.h | 26 +++++++++++++ plugins/MirLua/src/mlua_script.cpp | 54 ++------------------------ plugins/MirLua/src/mlua_script.h | 10 +---- plugins/MirLua/src/stdafx.h | 1 + 12 files changed, 137 insertions(+), 96 deletions(-) create mode 100644 plugins/MirLua/src/mlua_enviroment.cpp create mode 100644 plugins/MirLua/src/mlua_enviroment.h diff --git a/plugins/MirLua/src/m_core.cpp b/plugins/MirLua/src/m_core.cpp index 2042aa57bd..07c409a710 100644 --- a/plugins/MirLua/src/m_core.cpp +++ b/plugins/MirLua/src/m_core.cpp @@ -35,26 +35,26 @@ int HookEventLuaStateParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param return lua_tointeger(L, -1); } -int HookEventScriptParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) +int HookEventEnvParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) { - CMLuaScript *script = (CMLuaScript*)obj; + CMLuaEnviroment *env = (CMLuaEnviroment*)obj; int ref = param; - lua_rawgeti(script->L, LUA_REGISTRYINDEX, ref); + lua_rawgeti(env->L, LUA_REGISTRYINDEX, ref); if (wParam) - lua_pushlightuserdata(script->L, (void*)wParam); + lua_pushlightuserdata(env->L, (void*)wParam); else - lua_pushnil(script->L); + lua_pushnil(env->L); if (lParam) - lua_pushlightuserdata(script->L, (void*)lParam); + lua_pushlightuserdata(env->L, (void*)lParam); else - lua_pushnil(script->L); + lua_pushnil(env->L); - luaM_pcall(script->L, 2, 1); + luaM_pcall(env->L, 2, 1); - return lua_tointeger(script->L, -1); + return lua_tointeger(env->L, -1); } static int core_HookEvent(lua_State *L) @@ -66,9 +66,9 @@ static int core_HookEvent(lua_State *L) int ref = luaL_ref(L, LUA_REGISTRYINDEX); HANDLE res = NULL; - CMLuaScript *script = CMLuaScript::GetScriptFromEnviroment(L); - if (script) - res = HookEventObjParam(name, HookEventScriptParam, script, ref); + CMLuaEnviroment *env = CMLuaEnviroment::GetEnviroment(L); + if (env) + res = HookEventObjParam(name, HookEventEnvParam, env, ref); else res = HookEventObjParam(name, HookEventLuaStateParam, L, ref); if (res == NULL) @@ -95,9 +95,9 @@ static int core_HookTemporaryEvent(lua_State *L) int ref = luaL_ref(L, LUA_REGISTRYINDEX); HANDLE res = NULL; - CMLuaScript *script = CMLuaScript::GetScriptFromEnviroment(L); - if (script) - res = HookEventObjParam(name, HookEventScriptParam, script, ref); + CMLuaEnviroment *env = CMLuaEnviroment::GetEnviroment(L); + if (env) + res = HookEventObjParam(name, HookEventEnvParam, env, ref); else res = HookEventObjParam(name, HookEventLuaStateParam, L, ref); // event does not exists, call hook immideatelly @@ -106,7 +106,7 @@ static int core_HookTemporaryEvent(lua_State *L) lua_pushnil(L); lua_pushnil(L); luaM_pcall(L, 2, 1); - return lua_tointeger(script->L, -1); + return lua_tointeger(env->L, -1); } CMLua::HookRefs.insert(new HandleRefParam(L, res, ref)); @@ -169,19 +169,19 @@ INT_PTR CreateServiceFunctionLuaStateParam(void *obj, WPARAM wParam, LPARAM lPar return res; } -INT_PTR CreateServiceFunctionScriptParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) +INT_PTR CreateServiceFunctionEnvParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) { - CMLuaScript *script = (CMLuaScript*)obj; + CMLuaEnviroment *env = (CMLuaEnviroment*)obj; int ref = param; - lua_rawgeti(script->L, LUA_REGISTRYINDEX, ref); + lua_rawgeti(env->L, LUA_REGISTRYINDEX, ref); - lua_pushlightuserdata(script->L, (void*)wParam); - lua_pushlightuserdata(script->L, (void*)lParam); - luaM_pcall(script->L, 2, 1); + lua_pushlightuserdata(env->L, (void*)wParam); + lua_pushlightuserdata(env->L, (void*)lParam); + luaM_pcall(env->L, 2, 1); - INT_PTR res = lua_tointeger(script->L, 1); - lua_pushinteger(script->L, res); + INT_PTR res = lua_tointeger(env->L, 1); + lua_pushinteger(env->L, res); return res; } @@ -195,9 +195,9 @@ static int core_CreateServiceFunction(lua_State *L) int ref = luaL_ref(L, LUA_REGISTRYINDEX); HANDLE res = NULL; - CMLuaScript *script = CMLuaScript::GetScriptFromEnviroment(L); - if (script) - res = CreateServiceFunctionObjParam(name, CreateServiceFunctionScriptParam, script, ref); + CMLuaEnviroment *env = CMLuaEnviroment::GetEnviroment(L); + if (env) + res = CreateServiceFunctionObjParam(name, CreateServiceFunctionEnvParam, env, ref); else res = CreateServiceFunctionObjParam(name, CreateServiceFunctionLuaStateParam, L, ref); if (!res) diff --git a/plugins/MirLua/src/m_genmenu.cpp b/plugins/MirLua/src/m_genmenu.cpp index 9c549b6022..4814a7410e 100644 --- a/plugins/MirLua/src/m_genmenu.cpp +++ b/plugins/MirLua/src/m_genmenu.cpp @@ -2,7 +2,7 @@ void MakeMenuItem(lua_State *L, CMenuItem &mi) { - mi.hLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); + mi.hLangpack = CMLuaEnviroment::GetEnviromentId(L); lua_getfield(L, -1, "Flags"); mi.flags = lua_tointeger(L, -1); diff --git a/plugins/MirLua/src/m_hotkeys.cpp b/plugins/MirLua/src/m_hotkeys.cpp index faf1dbe6d0..6ab3f07625 100644 --- a/plugins/MirLua/src/m_hotkeys.cpp +++ b/plugins/MirLua/src/m_hotkeys.cpp @@ -41,7 +41,7 @@ static int hotkeys_Register(lua_State *L) HOTKEYDESC hk; MakeHotkey(L, hk); - int hScriptLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); + int hScriptLangpack = CMLuaEnviroment::GetEnviromentId(L); INT_PTR res = Hotkey_Register(&hk, hScriptLangpack); lua_pushboolean(L, res); diff --git a/plugins/MirLua/src/m_icolib.cpp b/plugins/MirLua/src/m_icolib.cpp index 48e5eeadd5..d2904be320 100644 --- a/plugins/MirLua/src/m_icolib.cpp +++ b/plugins/MirLua/src/m_icolib.cpp @@ -67,13 +67,12 @@ static int lua_AddIcon(lua_State *L) GetModuleFileName(g_hInstance, sid.defaultFile.w, MAX_PATH); } } - else if(lua_type(L, 1) == LUA_TTABLE) + else if (lua_type(L, 1) == LUA_TTABLE) MakeSKINICONDESC(L, sid); else luaL_argerror(L, 1, luaL_typename(L, 1)); - int hScriptLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); - + int hScriptLangpack = CMLuaEnviroment::GetEnviromentId(L); HANDLE res = IcoLib_AddIcon(&sid, hScriptLangpack); lua_pushlightuserdata(L, res); @@ -87,7 +86,6 @@ static int lua_AddIcon(lua_State *L) static int lua_GetIcon(lua_State *L) { - luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); bool big = luaM_toboolean(L, 2); HICON hIcon = NULL; @@ -142,6 +140,7 @@ static luaL_Reg icolibApi[] = { { "AddIcon", lua_AddIcon }, { "GetIcon", lua_GetIcon }, + { "GetHandle", lua_GetIconHandle }, { "GetIconHandle", lua_GetIconHandle }, { "RemoveIcon", lua_RemoveIcon }, diff --git a/plugins/MirLua/src/m_options.cpp b/plugins/MirLua/src/m_options.cpp index 95330c4bea..ee968a6982 100644 --- a/plugins/MirLua/src/m_options.cpp +++ b/plugins/MirLua/src/m_options.cpp @@ -44,7 +44,7 @@ public: void MakeOptionDialogPage(lua_State *L, OPTIONSDIALOGPAGE &odp) { odp.hInstance = g_hInstance; - odp.hLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); + odp.hLangpack = CMLuaEnviroment::GetEnviromentId(L); lua_getfield(L, -1, "Flags"); odp.flags = luaL_optinteger(L, -1, ODPF_BOLDGROUPS | ODPF_UNICODE | ODPF_DONTTRANSLATE); diff --git a/plugins/MirLua/src/m_sounds.cpp b/plugins/MirLua/src/m_sounds.cpp index 7c044caaee..2acd36f203 100644 --- a/plugins/MirLua/src/m_sounds.cpp +++ b/plugins/MirLua/src/m_sounds.cpp @@ -7,7 +7,7 @@ static int lua_AddSound(lua_State *L) ptrW section(mir_utf8decodeW(luaL_optstring(L, 3, MODULE))); ptrW filePath(mir_utf8decodeW(lua_tostring(L, 4))); - int res = Skin_AddSound(name, section, description, filePath, CMLuaScript::GetScriptIdFromEnviroment(L)); + int res = Skin_AddSound(name, section, description, filePath, CMLuaEnviroment::GetEnviromentId(L)); lua_pushboolean(L, res == 0); return 1; diff --git a/plugins/MirLua/src/m_srmm.cpp b/plugins/MirLua/src/m_srmm.cpp index fd7ae9e130..d29ca0d901 100644 --- a/plugins/MirLua/src/m_srmm.cpp +++ b/plugins/MirLua/src/m_srmm.cpp @@ -47,7 +47,7 @@ static int lua_AddButton(lua_State *L) BBButton bbb = { }; MakeBBButton(L, bbb); - int hScriptLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); + int hScriptLangpack = CMLuaEnviroment::GetEnviromentId(L); INT_PTR res = Srmm_AddButton(&bbb, hScriptLangpack); CleanBBButton(bbb); diff --git a/plugins/MirLua/src/mlua_enviroment.cpp b/plugins/MirLua/src/mlua_enviroment.cpp new file mode 100644 index 0000000000..5d3b7cf37c --- /dev/null +++ b/plugins/MirLua/src/mlua_enviroment.cpp @@ -0,0 +1,71 @@ +#include "stdafx.h" + +#define MT_ENVIROMENT "ENVIROMENT" + +CMLuaEnviroment::CMLuaEnviroment(lua_State *L) + : L(L) +{ + MUUID muidLast = MIID_LAST; + id = GetPluginLangId(muidLast, 0); +} + +CMLuaEnviroment* CMLuaEnviroment::GetEnviroment(lua_State *L) +{ + if (!luaM_getenv(L)) + return NULL; + + lua_rawgeti(L, -1, NULL); + CMLuaEnviroment *env = (CMLuaEnviroment*)lua_touserdata(L, -1); + lua_pop(L, 3); + + return env; +} + +int CMLuaEnviroment::GetEnviromentId(lua_State *L) +{ + CMLuaEnviroment *script = GetEnviroment(L); + return script != nullptr + ? script->GetId() + : hMLuaLangpack; +} + +int CMLuaEnviroment::GetId() const +{ + return id; +} + +void CMLuaEnviroment::CreateEnviromentTable() +{ + lua_createtable(L, 1, 1); + lua_pushlightuserdata(L, this); + lua_rawseti(L, -2, NULL); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_G"); + lua_createtable(L, 0, 2); + lua_pushliteral(L, MT_ENVIROMENT); + lua_setfield(L, -2, "__metatable"); + lua_getglobal(L, "_G"); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); +} + +bool CMLuaEnviroment::Load(int ind) +{ + luaL_checktype(L, ind, LUA_TFUNCTION); + + CreateEnviromentTable(); + lua_setupvalue(L, -2, 1); + + return luaM_pcall(L, 0, 1) == LUA_OK; +} + +void CMLuaEnviroment::Unload() +{ + KillModuleIcons(id); + KillModuleSounds(id); + KillModuleMenus(id); + KillModuleHotkeys(id); + + KillObjectEventHooks(this); + KillObjectServices(this); +} \ No newline at end of file diff --git a/plugins/MirLua/src/mlua_enviroment.h b/plugins/MirLua/src/mlua_enviroment.h new file mode 100644 index 0000000000..4366d58d03 --- /dev/null +++ b/plugins/MirLua/src/mlua_enviroment.h @@ -0,0 +1,26 @@ +#ifndef _LUA_ENVIROMENT_H_ +#define _LUA_ENVIROMENT_H_ + +class CMLuaEnviroment +{ +private: + int id; + + void CreateEnviromentTable(); + +public: + lua_State *L; + + CMLuaEnviroment(lua_State *L); + virtual ~CMLuaEnviroment() { } + + static CMLuaEnviroment* GetEnviroment(lua_State *L); + static int GetEnviromentId(lua_State *L); + + int GetId() const; + + bool Load(int ind); + void Unload(); +}; + +#endif //_LUA_ENVIROMENT_H_ diff --git a/plugins/MirLua/src/mlua_script.cpp b/plugins/MirLua/src/mlua_script.cpp index 280452d068..6fbcfc9ac7 100644 --- a/plugins/MirLua/src/mlua_script.cpp +++ b/plugins/MirLua/src/mlua_script.cpp @@ -3,7 +3,7 @@ #define MT_SCRIPT "SCRIPT" CMLuaScript::CMLuaScript(lua_State *L, const wchar_t *path) - : L(L), status(None), unloadRef(LUA_NOREF) + : CMLuaEnviroment(L) { mir_wstrcpy(filePath, path); @@ -16,9 +16,6 @@ CMLuaScript::CMLuaScript(lua_State *L, const wchar_t *path) mir_wstrncpy(name, fileName, length); moduleName = mir_utf8encodeW(name); - - MUUID muidLast = MIID_LAST; - id = GetPluginLangId(muidLast, 0); } CMLuaScript::~CMLuaScript() @@ -26,32 +23,6 @@ CMLuaScript::~CMLuaScript() mir_free(moduleName); } -CMLuaScript* CMLuaScript::GetScriptFromEnviroment(lua_State *L) -{ - if (!luaM_getenv(L)) - return NULL; - - lua_rawgeti(L, -1, NULL); - CMLuaScript *script = (CMLuaScript*)lua_touserdata(L, -1); - lua_pop(L, 3); - - return script; -} - -int CMLuaScript::GetScriptIdFromEnviroment(lua_State *L) -{ - CMLuaScript *script = GetScriptFromEnviroment(L); - if (script != NULL) - return script->GetId(); - - return hMLuaLangpack; -} - -int CMLuaScript::GetId() const -{ - return id; -} - const char* CMLuaScript::GetModuleName() const { return moduleName; @@ -82,20 +53,7 @@ bool CMLuaScript::Load() return false; } - lua_createtable(L, 1, 1); - lua_pushlightuserdata(L, this); - lua_rawseti(L, -2, NULL); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "_G"); - lua_createtable(L, 0, 2); - lua_pushliteral(L, MT_SCRIPT); - lua_setfield(L, -2, "__metatable"); - lua_getglobal(L, "_G"); - lua_setfield(L, -2, "__index"); - lua_setmetatable(L, -2); - lua_setupvalue(L, -2, 1); - - if (luaM_pcall(L, 0, 1)) + if (!CMLuaEnviroment::Load(-1)) return false; status = Loaded; @@ -154,11 +112,5 @@ void CMLuaScript::Unload() lua_setfield(L, -2, moduleName); lua_pop(L, 1); - KillModuleIcons(id); - KillModuleSounds(id); - KillModuleMenus(id); - KillModuleHotkeys(id); - - KillObjectEventHooks(this); - KillObjectServices(this); + CMLuaEnviroment::Unload(); } \ No newline at end of file diff --git a/plugins/MirLua/src/mlua_script.h b/plugins/MirLua/src/mlua_script.h index 539a0123b8..2b5d57d7c7 100644 --- a/plugins/MirLua/src/mlua_script.h +++ b/plugins/MirLua/src/mlua_script.h @@ -1,11 +1,9 @@ #ifndef _LUA_SCRIPT_H_ #define _LUA_SCRIPT_H_ -class CMLuaScript +class CMLuaScript : public CMLuaEnviroment { public: - lua_State *L; - enum Status { None, @@ -14,7 +12,6 @@ public: }; private: - int id; int unloadRef; char *moduleName; wchar_t *fileName; @@ -25,11 +22,6 @@ public: CMLuaScript(lua_State *L, const wchar_t *path); ~CMLuaScript(); - static CMLuaScript* GetScriptFromEnviroment(lua_State *L); - static int GetScriptIdFromEnviroment(lua_State *L); - - int GetId() const; - const char* GetModuleName() const; const wchar_t* GetFilePath() const; diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h index 84924a7012..d9fb9febc4 100644 --- a/plugins/MirLua/src/stdafx.h +++ b/plugins/MirLua/src/stdafx.h @@ -33,6 +33,7 @@ class CMLuaScript; #include "mlua.h" +#include "mlua_enviroment.h" #include "mlua_script.h" #include "mlua_module_loader.h" #include "mlua_script_loader.h" -- cgit v1.2.3