From 02811b72f62e51a80a20c5816d2936e417cc7656 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 23 Jan 2024 22:43:25 +0100 Subject: [PATCH 1/4] Fix segfault when trying to spawn an MT_PLAYER from Lua --- src/lua_baselib.c | 4 ++-- src/p_local.h | 2 +- src/p_mobj.c | 18 ++++++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e75a911ee..d6f125bbd 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -641,7 +641,7 @@ static int lib_pSpawnMobj(lua_State *L) NOHUD INLEVEL NOSPAWNNULL - LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); + LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ); return 1; } @@ -657,7 +657,7 @@ static int lib_pSpawnMobjFromMobj(lua_State *L) NOSPAWNNULL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); + LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type, NULL), META_MOBJ); return 1; } diff --git a/src/p_local.h b/src/p_local.h index 0bcd6da1d..7e4741ffd 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -328,7 +328,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(ffloor_t *rover); void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype); -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...); mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type); mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z); diff --git a/src/p_mobj.c b/src/p_mobj.c index 55be8e54f..c6f437c9a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14420,15 +14420,29 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) // Spawns an object with offsets relative to the position of another object. // Scale, gravity flip, etc. is taken into account automatically. // -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...) { + va_list args; mobj_t *newmobj; xofs = FixedMul(xofs, mobj->scale); yofs = FixedMul(yofs, mobj->scale); zofs = FixedMul(zofs, mobj->scale); - newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); + if (type == MT_PLAYER) + { + player_t *player; + // MT_PLAYER requires an additional parameter for the player, so pass that forth. + va_start(args, type); + player = va_arg(args, player_t *); + va_end(args); + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, player); + } + else + { + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); + } + if (!newmobj) return NULL; From 259997d121c0bc32cbcc062fc52507f381a21668 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 24 Jan 2024 17:11:04 +0100 Subject: [PATCH 2/4] Remove varargs from P_SpawnMobjFromMobj --- src/lua_baselib.c | 2 +- src/p_local.h | 2 +- src/p_mobj.c | 16 ++-------------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d6f125bbd..47ee3976d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -657,7 +657,7 @@ static int lib_pSpawnMobjFromMobj(lua_State *L) NOSPAWNNULL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type, NULL), META_MOBJ); + LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); return 1; } diff --git a/src/p_local.h b/src/p_local.h index 7e4741ffd..0bcd6da1d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -328,7 +328,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(ffloor_t *rover); void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype); -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...); +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type); mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z); diff --git a/src/p_mobj.c b/src/p_mobj.c index c6f437c9a..3999c9476 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14420,7 +14420,7 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) // Spawns an object with offsets relative to the position of another object. // Scale, gravity flip, etc. is taken into account automatically. // -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...) +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) { va_list args; mobj_t *newmobj; @@ -14429,19 +14429,7 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo yofs = FixedMul(yofs, mobj->scale); zofs = FixedMul(zofs, mobj->scale); - if (type == MT_PLAYER) - { - player_t *player; - // MT_PLAYER requires an additional parameter for the player, so pass that forth. - va_start(args, type); - player = va_arg(args, player_t *); - va_end(args); - newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, player); - } - else - { - newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); - } + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, NULL); if (!newmobj) return NULL; From b3aa23bc214e3aee7accca87d820c7943f012c13 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 24 Jan 2024 16:13:34 +0000 Subject: [PATCH 3/4] Remove unused variable --- src/p_mobj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3999c9476..4bed833fb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14422,7 +14422,6 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) // mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) { - va_list args; mobj_t *newmobj; xofs = FixedMul(xofs, mobj->scale); From 51e912e87be2dac061565bddeb1b0e56e867d71b Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 5 Mar 2024 18:29:07 +0100 Subject: [PATCH 4/4] Fix segfault when passing NULL as player --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4bed833fb..84884eef3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10886,7 +10886,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) // when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj. va_start(args, type); mobj->player = va_arg(args, player_t *); - mobj->player->mo = mobj; + if (mobj->player) + mobj->player->mo = mobj; va_end(args); }