From: nethack.allison Date: Wed, 3 Jul 2002 02:22:50 +0000 (+0000) Subject: B01012 involuntary dismount crash X-Git-Tag: MOVE2GIT~2686 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d402e1b07f77db2cf68465a1b9cff105da44c87;p=nethack B01012 involuntary dismount crash Nethack crashes when you are riding a flying monster over a pool/moat and some engulfing monster plucks you off your saddle. After falling into the water you'll get the normal message sequence (sink like rock ... phew, that was close; you also get chance to teleport if you can). After the last message the game will crash with a segmentation fault. - reproducible; null pointer dereference in swallowed() The crash results because dismount_steed() calls float_down(), which calls drown(), which calls teleds(), which clears u.ustuck. So when gulpmu calls swallowed after dismount_steed(), this line attempts to derefernce a null pointer: swallower = monsndx(u.ustuck->data); This patch bypasses the float_down() in dismount steed() altogether. That routine is meant to return the hero to the floor, and that isn't appropriate if a purple worm just plucked you off the steed anyway. While this fixes the crash, a problem still exists. The way swallowing works, the swallowing monster's location switches to that of the hero. Since that location is over water, the purple worm ends up drowning almost immediately after you are swallowed, while you are swallowed. The purple worm's death is not revealed to you since the "The purple worm drowns." message is conditional. This patch also adds a message when the purple worm dies, but should this guaranteed drowing take place? --- diff --git a/src/mon.c b/src/mon.c index 9cd977080..050d341d6 100644 --- a/src/mon.c +++ b/src/mon.c @@ -400,6 +400,12 @@ register struct monst *mtmp; if (cansee(mtmp->mx,mtmp->my)) { pline("%s drowns.", Monnam(mtmp)); } + if (u.ustuck && u.uswallow && u.ustuck == mtmp) { + /* This can happen after a purple worm plucks you off a + flying steed while you are over water. */ + pline("%s sinks as water rushes in and flushes you out.", + Monnam(mtmp)); + } mondead(mtmp); if (mtmp->mhp > 0) { rloc(mtmp); diff --git a/src/steed.c b/src/steed.c index 9ad44b267..791b61f97 100644 --- a/src/steed.c +++ b/src/steed.c @@ -588,14 +588,14 @@ dismount_steed(reason) } /* Return the player to the floor */ + if (reason != DISMOUNT_ENGULFED) { in_steed_dismounting = TRUE; (void) float_down(0L, W_SADDLE); in_steed_dismounting = FALSE; flags.botl = 1; - if (reason != DISMOUNT_ENGULFED) { - (void)encumber_msg(); - vision_full_recalc = 1; - } + (void)encumber_msg(); + vision_full_recalc = 1; + } else flags.botl = 1; return; }