]> granicus.if.org Git - nethack/commitdiff
B01012 involuntary dismount crash
authornethack.allison <nethack.allison>
Wed, 3 Jul 2002 02:22:50 +0000 (02:22 +0000)
committernethack.allison <nethack.allison>
Wed, 3 Jul 2002 02:22:50 +0000 (02:22 +0000)
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?

src/mon.c
src/steed.c

index 9cd9770805e9a161b04299984738584f01177a97..050d341d667838c2d8c2c937531f748d1f074e85 100644 (file)
--- 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);
index 9ad44b267cc234b69c3e82508183c6f2604003f3..791b61f97a6d1e7ddf9d6d7a45292859230ed160 100644 (file)
@@ -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;
 }