From: Pasi Kallinen Date: Sat, 18 Apr 2020 13:51:35 +0000 (+0300) Subject: Fix segfault on teleport while punished due to flooreffects X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2d43c6d62a0a306ca503affecf82b8acb4c65bb0;p=nethack Fix segfault on teleport while punished due to flooreffects ... 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. --- diff --git a/src/do.c b/src/do.c index 15b43397e..21f092c46 100644 --- 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); diff --git a/src/teleport.c b/src/teleport.c index 38baddb4b..fe03207bf 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -372,7 +372,7 @@ int teleds_flags; the old position if allow_drag is true... */ u_on_newpos(nux, nuy); /* set u., usteed->; 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();