From 8dad46a751af4ae1af45ffb00c1f239802bd93d8 Mon Sep 17 00:00:00 2001 From: Gondos Date: Sun, 1 Dec 2024 16:52:34 +0100 Subject: [PATCH] [Lua]Harden vessel dereferencing --- Src/Module/LuaScript/LuaInline/LuaInline.cpp | 4 ++++ Src/Module/LuaScript/LuaInline/LuaInline.h | 9 +++---- .../LuaScript/LuaInterpreter/Interpreter.cpp | 22 +++++++---------- .../LuaScript/LuaInterpreter/Interpreter.h | 6 ++--- .../LuaInterpreter/lua_vessel_mtd.cpp | 24 ++++++++++++------- .../LuaScript/LuaInterpreter/lua_xrsound.cpp | 3 +-- Src/Vessel/DeltaGlider/DGLua.cpp | 2 +- Src/Vessel/HST/HST_Lua.cpp | 4 ++-- Src/Vessel/Quadcopter/QuadcopterLua.cpp | 4 ++-- Src/Vessel/ShuttleA/ShuttleALua.cpp | 2 +- Src/Vessel/Solarsail/SailLua.cpp | 6 ++--- 11 files changed, 45 insertions(+), 41 deletions(-) diff --git a/Src/Module/LuaScript/LuaInline/LuaInline.cpp b/Src/Module/LuaScript/LuaInline/LuaInline.cpp index 970c7b983..4f3e6ee67 100644 --- a/Src/Module/LuaScript/LuaInline/LuaInline.cpp +++ b/Src/Module/LuaScript/LuaInline/LuaInline.cpp @@ -135,6 +135,10 @@ void InterpreterList::clbkPostStep (double simt, double simdt, double mjd) } } +void InterpreterList::clbkDeleteVessel (OBJHANDLE hVessel) +{ + Interpreter::DeleteVessel(hVessel); +} InterpreterList::Environment *InterpreterList::AddInterpreter () { diff --git a/Src/Module/LuaScript/LuaInline/LuaInline.h b/Src/Module/LuaScript/LuaInline/LuaInline.h index 1c0fa3d90..566c2a379 100644 --- a/Src/Module/LuaScript/LuaInline/LuaInline.h +++ b/Src/Module/LuaScript/LuaInline/LuaInline.h @@ -45,10 +45,11 @@ class InterpreterList: public oapi::Module { InterpreterList (HINSTANCE hDLL); ~InterpreterList (); - void clbkSimulationEnd (); - void clbkPostStep (double simt, double simdt, double mjd); - void clbkSimulationStart (RenderMode mode); - + void clbkSimulationEnd () override; + void clbkPostStep (double simt, double simdt, double mjd) override; + void clbkSimulationStart (RenderMode mode) override; + void clbkDeleteVessel (OBJHANDLE hVessel) override; + Environment *AddInterpreter (); int DelInterpreter (Environment *env); diff --git a/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp b/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp index d1a1dfa0f..b04b568f5 100644 --- a/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp +++ b/Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp @@ -520,7 +520,7 @@ void Interpreter::lua_pushvessel (lua_State *L, VESSEL *v) lua_pop(L,1); // pop nil VESSEL **pv = (VESSEL**)lua_newuserdata(L,sizeof(VESSEL*)); *pv = v; - knownVessels.insert(pv); + knownVessels.insert(v); luaL_getmetatable (L, "VESSEL.vtable"); // retrieve metatable lua_setmetatable (L,-2); // and attach to new object LoadVesselExtensions(L,v); // vessel environment @@ -530,17 +530,6 @@ void Interpreter::lua_pushvessel (lua_State *L, VESSEL *v) // note that now the object is on top of the stack } } -int Interpreter::lua_isvessel(lua_State *L, int idx) -{ - if(lua_isuserdata(L, idx)) { - void *ud = lua_touserdata(L, idx); - if(knownVessels.find(ud)!=knownVessels.end()) { - return true; - } - } - luaL_error(L, "Invalid parameter %d, vessel expected", idx); - return false; -} void Interpreter::lua_pushmfd (lua_State *L, MFD2 *mfd) { @@ -1658,6 +1647,12 @@ bool Interpreter::LoadVesselExtensions (lua_State *L, VESSEL *v) return (v3->clbkGeneric (VMSG_LUAINSTANCE, 0, (void*)L) != 0); } +void Interpreter::DeleteVessel (OBJHANDLE hVessel) +{ + VESSEL *v = oapiGetVesselInterface(hVessel); + knownVessels.erase(v); +} + Interpreter *Interpreter::GetInterpreter (lua_State *L) { lua_getfield (L, LUA_REGISTRYINDEX, "interp"); @@ -6119,8 +6114,7 @@ int Interpreter::oapi_setup_customcamera(lua_State *L) void *ud = lua_touserdata(L,2); if(oapiIsVessel(ud)) { hVessel = (OBJHANDLE)ud; - } else if(lua_isvessel(L, 2)) { - VESSEL *v = (VESSEL *)lua_tovessel(L, 2); + } else if(VESSEL *v = lua_tovessel(L, 2)) { hVessel = v->GetHandle(); } else { luaL_error(L, "vessel of vessel handle expected"); diff --git a/Src/Module/LuaScript/LuaInterpreter/Interpreter.h b/Src/Module/LuaScript/LuaInterpreter/Interpreter.h index b6b1af86d..d9c199db7 100644 --- a/Src/Module/LuaScript/LuaInterpreter/Interpreter.h +++ b/Src/Module/LuaScript/LuaInterpreter/Interpreter.h @@ -235,6 +235,7 @@ class INTERPRETERLIB Interpreter { static int LuaCall(lua_State *L, int nargs, int nres); void SetErrorBox(NOTEHANDLE eb) { errorbox = eb; } + static void DeleteVessel (OBJHANDLE hVessel); protected: static inline NOTEHANDLE errorbox; lua_State *L; // Lua main context @@ -304,12 +305,11 @@ class INTERPRETERLIB Interpreter { // Pops a VESSEL interface from the stack and returns it. // A NULL return indicates an invalid data type at the specified stack position, - // but a nonzero return does not guarantee a valid vessel pointer + // a nonzero return guarantees a valid vessel pointer static VESSEL *lua_tovessel (lua_State *L, int idx=-1); // type extraction with checks static VESSEL *lua_tovessel_safe (lua_State *L, int idx, const char *funcname); - static int lua_isvessel(lua_State *L, int idx); static int lua_tointeger_safe (lua_State *L, int idx, const char *funcname); static double lua_tonumber_safe (lua_State *L, int idx, const char *funcname); @@ -1155,7 +1155,7 @@ class INTERPRETERLIB Interpreter { int (*postfunc)(void*); void *postcontext; - static inline std::unordered_setknownVessels; // for lua_isvessel + static inline std::unordered_setknownVessels; // for lua_isvessel static int lua_tointeger_safe (lua_State *L, int idx, int prmno, const char *funcname); diff --git a/Src/Module/LuaScript/LuaInterpreter/lua_vessel_mtd.cpp b/Src/Module/LuaScript/LuaInterpreter/lua_vessel_mtd.cpp index 6904033a3..a5a41f52f 100644 --- a/Src/Module/LuaScript/LuaInterpreter/lua_vessel_mtd.cpp +++ b/Src/Module/LuaScript/LuaInterpreter/lua_vessel_mtd.cpp @@ -44,18 +44,24 @@ VESSEL *vfocus = (VESSEL*)0x1; VESSEL *Interpreter::lua_tovessel (lua_State *L, int idx) { VESSEL **pv = (VESSEL**)lua_touserdata (L, idx); - if (pv && *pv == vfocus) // replace flag with actual focus vessel pointer - *pv = oapiGetFocusInterface(); - return pv ? *pv : NULL; + if(pv) { + if (*pv == vfocus) { // returns current focused vessel when using the pseudo vessel "focus" + VESSEL *v = oapiGetFocusInterface(); + knownVessels.insert(v); + return v; + } else if(knownVessels.find(*pv) == knownVessels.end()) { + return NULL; + } + return *pv; + } + return NULL; } VESSEL *Interpreter::lua_tovessel_safe(lua_State *L, int idx, const char *funcname) { VESSEL *v = lua_tovessel(L,idx); if (!v) { - char cbuf[1024]; - sprintf(cbuf, "%s: invalid vessel object for self", funcname); - term_strout(L, cbuf); + luaL_error(L, "Invalid vessel object for self"); } return v; } @@ -566,7 +572,7 @@ void Interpreter::LoadVesselAPI () luaL_openlib (L, "vessel", vesselAcc, 0); // create pseudo-instance "focus" - lua_pushlightuserdata (L, vfocus); + lua_pushlightuserdata (L, &vfocus); luaL_getmetatable (L, "VESSEL.vtable"); // push metatable lua_setmetatable (L, -2); // set metatable for user data lua_setglobal (L, "focus"); @@ -8610,7 +8616,7 @@ int Interpreter::v_register_panelarea(lua_State* L) { static const char* funcname = "register_panelarea"; VESSEL* v = lua_tovessel_safe(L, 1, funcname); - if (v->Version() < 3) { + if (v->Version() < 3) { lua_pushnil(L); lua_pushstring(L, "Invalid vessel version in register_panelarea"); return 2; @@ -8685,7 +8691,7 @@ int Interpreter::v_register_panelmfdgeometry (lua_State *L) { static const char* funcname = "register_panelmfdgeometry"; VESSEL* v = lua_tovessel_safe(L, 1, funcname); - if (v->Version() < 2) { + if (v->Version() < 2) { lua_pushnil(L); lua_pushstring(L, "Invalid vessel version in register_panelmfdgeometry"); return 2; diff --git a/Src/Module/LuaScript/LuaInterpreter/lua_xrsound.cpp b/Src/Module/LuaScript/LuaInterpreter/lua_xrsound.cpp index cd58e0e1a..11f1f56b5 100644 --- a/Src/Module/LuaScript/LuaInterpreter/lua_xrsound.cpp +++ b/Src/Module/LuaScript/LuaInterpreter/lua_xrsound.cpp @@ -141,8 +141,7 @@ int Interpreter::xrsound_create_instance (lua_State *L) if(lua_isstring(L, 1)) { const char *moduleName = lua_tostring(L, 1); snd = XRSound::CreateInstance(moduleName); - } else if (lua_isvessel(L, 1)) { - VESSEL *v = lua_tovessel(L, 1); + } else if (VESSEL *v = lua_tovessel(L, 1)) { snd = XRSound::CreateInstance(v); } else { return luaL_error(L, "Invalid parameter to xrsound.create_instance, string or vessel handle needed"); diff --git a/Src/Vessel/DeltaGlider/DGLua.cpp b/Src/Vessel/DeltaGlider/DGLua.cpp index 8c6605595..8e62ffed4 100644 --- a/Src/Vessel/DeltaGlider/DGLua.cpp +++ b/Src/Vessel/DeltaGlider/DGLua.cpp @@ -105,7 +105,7 @@ these methods for other vessel types will generally result in an error. To check DeltaGlider *lua_toDG (lua_State *L, int idx) { - VESSEL **pv = (VESSEL**)lua_touserdata (L, idx); + VESSEL **pv = (VESSEL **)luaL_checkudata(L, idx, "DG.vtable"); DeltaGlider *dg = (DeltaGlider*)*pv; return dg; } diff --git a/Src/Vessel/HST/HST_Lua.cpp b/Src/Vessel/HST/HST_Lua.cpp index 485ac3b6f..19d0a3ecd 100644 --- a/Src/Vessel/HST/HST_Lua.cpp +++ b/Src/Vessel/HST/HST_Lua.cpp @@ -43,7 +43,7 @@ int HST::Lua_InitInstance(void *context) { lua_State *L = (lua_State*)context; - // check if interpreter has DG table loaded already + // check if interpreter has HST table loaded already luaL_getmetatable (L, "VESSEL.HST"); if (lua_isnil (L, -1)) { // register new functions @@ -98,7 +98,7 @@ To check the class of a vessel object, use the vessel:get_classname() method. HST *lua_toHST (lua_State *L, int idx) { - VESSEL **pv = (VESSEL**)lua_touserdata (L, idx); + VESSEL **pv = (VESSEL **)luaL_checkudata(L, idx, "HST.vtable"); HST *hst = (HST*)*pv; return hst; } diff --git a/Src/Vessel/Quadcopter/QuadcopterLua.cpp b/Src/Vessel/Quadcopter/QuadcopterLua.cpp index 5f5e85db6..101571d11 100644 --- a/Src/Vessel/Quadcopter/QuadcopterLua.cpp +++ b/Src/Vessel/Quadcopter/QuadcopterLua.cpp @@ -26,7 +26,7 @@ int LuaInterface::InitInstance(void *context) { lua_State *L = (lua_State*)context; - // check if interpreter has DG table loaded already + // check if interpreter has QC table loaded already luaL_getmetatable(L, "VESSEL.QC"); if (lua_isnil(L, -1)) { // register new functions @@ -85,7 +85,7 @@ To check the class of a vessel object, use the vessel:get_classname() method. Quadcopter *LuaInterface::lua_toQC(lua_State *L, int idx) { - VESSEL **pv = (VESSEL**)lua_touserdata(L, idx); + VESSEL **pv = (VESSEL **)luaL_checkudata(L, idx, "QC.vtable"); Quadcopter *qc = (Quadcopter*)*pv; return qc; } diff --git a/Src/Vessel/ShuttleA/ShuttleALua.cpp b/Src/Vessel/ShuttleA/ShuttleALua.cpp index b0e5a55ee..da0f17bc3 100644 --- a/Src/Vessel/ShuttleA/ShuttleALua.cpp +++ b/Src/Vessel/ShuttleA/ShuttleALua.cpp @@ -102,7 +102,7 @@ VECTOR3 lua_tovector (lua_State *L, int idx) ShuttleA *lua_toShuttleA (lua_State *L, int idx) { - VESSEL **pv = (VESSEL**)lua_touserdata (L, idx); + VESSEL **pv = (VESSEL **)luaL_checkudata(L, idx, "SHUTTLEA.vtable"); ShuttleA *sh = (ShuttleA*)*pv; return sh; } diff --git a/Src/Vessel/Solarsail/SailLua.cpp b/Src/Vessel/Solarsail/SailLua.cpp index 94ea3b4ff..ea00da00e 100644 --- a/Src/Vessel/Solarsail/SailLua.cpp +++ b/Src/Vessel/Solarsail/SailLua.cpp @@ -35,8 +35,8 @@ int SolarSail::Lua_InitInstance (void *context) { lua_State *L = (lua_State*)context; - // check if interpreter has DG table loaded already - luaL_getmetatable (L, "VESSEL.DG"); + // check if interpreter has SSail table loaded already + luaL_getmetatable (L, "VESSEL.SSail"); if (lua_isnil (L, -1)) { // register new functions lua_pop (L, 1); @@ -88,7 +88,7 @@ To check the class of a vessel object, use the vessel:get_classname() method. SolarSail *lua_toSSail (lua_State *L, int idx) { - VESSEL **pv = (VESSEL**)lua_touserdata (L, idx); + VESSEL **pv = (VESSEL **)luaL_checkudata(L, idx, "SSail.vtable"); SolarSail *sail = (SolarSail*)*pv; return sail; }