]> granicus.if.org Git - nethack/commitdiff
Fix segfault on teleport while punished due to flooreffects
authorPasi Kallinen <paxed@alt.org>
Sat, 18 Apr 2020 13:51:35 +0000 (16:51 +0300)
committerPasi Kallinen <paxed@alt.org>
Sat, 18 Apr 2020 15:58:39 +0000 (18:58 +0300)
... deleting the ball & chain, but keeping a boulder in the pit.

Noticed a segfault when fuzzing, teleport while punished caused
a segfault via fill_pit -> flooreffects -> bury_objs -> unpunish,
and then the next line in teleds tried to look up uchain.

Guard against that particular case.

Fix the case of boulder being in a pit, triggered by you being in
a pit and a giant throwing a boulder on top of you.

src/do.c
src/teleport.c

index 15b43397e922f47d6703cd0bcb71e45184bf1f3a..21f092c46f2b79804073f5137251babc3ceda965 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -195,7 +195,7 @@ const char *verb;
                 if (!Passes_walls && !throws_rocks(g.youmonst.data)) {
                     losehp(Maybe_Half_Phys(rnd(15)),
                            "squished under a boulder", NO_KILLER_PREFIX);
-                    return FALSE; /* player remains trapped */
+                    goto deletedwithboulder;
                 } else
                     reset_utrap(TRUE);
             }
@@ -219,6 +219,7 @@ const char *verb;
          * Note:  trap might have gone away via ((hmon -> killed -> xkilled)
          *  || mondied) -> mondead -> m_detach -> fill_pit.
          */
+deletedwithboulder:
         if ((t = t_at(x, y)) != 0)
             deltrap(t);
         useupf(obj, 1L);
index 38baddb4bd0fff7b832177a261c00461118ec059..fe03207bfee964636683a4a40a63a23a0411ac2e 100644 (file)
@@ -372,7 +372,7 @@ int teleds_flags;
        the old position if allow_drag is true... */
     u_on_newpos(nux, nuy); /* set u.<x,y>, usteed-><mx,my>; cliparound() */
     fill_pit(u.ux0, u.uy0);
-    if (ball_active && uchain->where == OBJ_FREE)
+    if (ball_active && uchain && uchain->where == OBJ_FREE)
         placebc(); /* put back the ball&chain if they were taken off map */
     initrack(); /* teleports mess up tracking monsters without this */
     update_player_regions();