commit 7172d2b93b5cac37e8fcd527b4237372653e640e
Author: Fabian Greffrath <fabian@greffrath.com>
AuthorDate: Tue Sep 16 20:13:25 2025 +0200
Commit: GitHub <noreply@github.com>
CommitDate: Tue Sep 16 20:13:25 2025 +0200
Hexen: Do not read `player` field from `struct degenmobj_t` (#1757)
* Hexen: Do not read `player` field from `struct degenmobj_t`
Fixes #1756
* invert logic and add comment
* raise an error in the thinker function to prevent it from being merged
---
src/hexen/p_local.h | 1 +
src/hexen/p_setup.c | 7 +++++++
src/hexen/po_man.c | 1 +
src/hexen/s_sound.c | 6 +++++-
4 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/hexen/p_local.h b/src/hexen/p_local.h
index 29ca0402..9bd92dd9 100644
--- a/src/hexen/p_local.h
+++ b/src/hexen/p_local.h
@@ -152,6 +152,7 @@ void P_ThrustMobj(mobj_t * mo, angle_t angle, fixed_t move);
int P_FaceMobj(mobj_t * source, mobj_t * target, angle_t * delta);
boolean P_SeekerMissile(mobj_t * actor, angle_t thresh, angle_t turnMax);
void P_MobjThinker(thinker_t *thinker);
+void P_DegenMobjThinker(thinker_t *thinker);
void P_BlasterMobjThinker(thinker_t *thinker);
void P_SpawnPuff(fixed_t x, fixed_t y, fixed_t z);
void P_SpawnBlood(fixed_t x, fixed_t y, fixed_t z, int damage);
diff --git a/src/hexen/p_setup.c b/src/hexen/p_setup.c
index 8fb1ea2e..d7190772 100644
--- a/src/hexen/p_setup.c
+++ b/src/hexen/p_setup.c
@@ -578,6 +578,12 @@ void P_LoadBlockMap(int lump)
=================
*/
+void P_DegenMobjThinker(thinker_t *thinker)
+{
+ (void) thinker;
+ I_Error("This function should never get called.");
+}
+
void P_GroupLines(void)
{
line_t **linebuffer;
@@ -634,6 +640,7 @@ void P_GroupLines(void)
// set the degenmobj_t to the middle of the bounding box
sector->soundorg.x = (bbox[BOXRIGHT] + bbox[BOXLEFT]) / 2;
sector->soundorg.y = (bbox[BOXTOP] + bbox[BOXBOTTOM]) / 2;
+ sector->soundorg.thinker.function = (think_t) P_DegenMobjThinker;
// adjust bounding box to map blocks
block = (bbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
diff --git a/src/hexen/po_man.c b/src/hexen/po_man.c
index 4fe33af6..89364ad5 100644
--- a/src/hexen/po_man.c
+++ b/src/hexen/po_man.c
@@ -1449,6 +1449,7 @@ void PO_Init(int lump)
{ // Polyobj StartSpot Pt.
polyobjs[polyIndex].startSpot.x = spawnthing.x << FRACBITS;
polyobjs[polyIndex].startSpot.y = spawnthing.y << FRACBITS;
+ polyobjs[polyIndex].startSpot.thinker.function = (think_t) P_DegenMobjThinker;
SpawnPolyobj(polyIndex, spawnthing.angle,
(spawnthing.type == PO_SPAWNCRUSH_TYPE));
polyIndex++;
diff --git a/src/hexen/s_sound.c b/src/hexen/s_sound.c
index eadba478..33e62167 100644
--- a/src/hexen/s_sound.c
+++ b/src/hexen/s_sound.c
@@ -416,7 +416,11 @@ void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume)
#endif
for (i = 0; i < snd_Channels; i++)
{
- if (origin->player)
+ // The origin pointer may point to an object of type degenmobj_t
+ // (i.e. sector_t.soundorg and polyobj_t.startSpot) which does not have
+ // a player element. Thus the origin->player pointer may point to
+ // random memory which most likely evaluates to true.
+ if (origin->thinker.function == P_DegenMobjThinker || origin->player)
{
i = snd_Channels;
break; // let the player have more than one sound.