foxygit / doom Log in
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.