Skip to content

Commit

Permalink
[Lua]Harden vessel dereferencing
Browse files Browse the repository at this point in the history
  • Loading branch information
TheGondos committed Dec 1, 2024
1 parent d4437e3 commit 8dad46a
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 41 deletions.
4 changes: 4 additions & 0 deletions Src/Module/LuaScript/LuaInline/LuaInline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
{
Expand Down
9 changes: 5 additions & 4 deletions Src/Module/LuaScript/LuaInline/LuaInline.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
22 changes: 8 additions & 14 deletions Src/Module/LuaScript/LuaInterpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
{
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
6 changes: 3 additions & 3 deletions Src/Module/LuaScript/LuaInterpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1155,7 +1155,7 @@ class INTERPRETERLIB Interpreter {
int (*postfunc)(void*);
void *postcontext;

static inline std::unordered_set<void *>knownVessels; // for lua_isvessel
static inline std::unordered_set<VESSEL *>knownVessels; // for lua_isvessel


static int lua_tointeger_safe (lua_State *L, int idx, int prmno, const char *funcname);
Expand Down
24 changes: 15 additions & 9 deletions Src/Module/LuaScript/LuaInterpreter/lua_vessel_mtd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions Src/Module/LuaScript/LuaInterpreter/lua_xrsound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion Src/Vessel/DeltaGlider/DGLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions Src/Vessel/HST/HST_Lua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions Src/Vessel/Quadcopter/QuadcopterLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion Src/Vessel/ShuttleA/ShuttleALua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions Src/Vessel/Solarsail/SailLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 8dad46a

Please sign in to comment.