fix #H6285 - flooreffects and deltrap panic

Reported 14 months ago, a monster reading a scroll of earth which
dropped a boulder that killed another monster in an adjacent pit
was giving credit/blame to the hero and could also trigger a panic.
If the monster was killed, the pit would be filled and deleted via
m_detach and then when flooreffects tried to delete the same trap,
it accessed freed memory and deltrap could panic.
This commit is contained in:
PatR
2019-01-16 15:08:11 -08:00
parent 521dbe8f94
commit b9f38fdd14
3 changed files with 61 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1547118630 2019/01/10 11:10:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.198 $ */
/* NetHack 3.6 uhitm.c $NHDT-Date: 1547680084 2019/01/16 23:08:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.199 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -923,13 +923,13 @@ int dieroll;
break;
#define useup_eggs(o) \
{ \
do { \
if (thrown) \
obfree(o, (struct obj *) 0); \
else \
useupall(o); \
o = (struct obj *) 0; \
} /* now gone */
} while (0) /* now gone */
case EGG: {
long cnt = obj->quan;
@@ -963,10 +963,11 @@ int dieroll;
break;
return (boolean) (!DEADMONSTER(mon));
} else { /* ordinary egg(s) */
const char *eggp =
(obj->corpsenm != NON_PM && obj->known)
? the(mons[obj->corpsenm].mname)
: (cnt > 1L) ? "some" : "an";
const char *eggp = (obj->corpsenm != NON_PM
&& obj->known)
? the(mons[obj->corpsenm].mname)
: (cnt > 1L) ? "some" : "an";
You("hit %s with %s egg%s.", mon_nam(mon), eggp,
plur(cnt));
if (touch_petrifies(mdat) && !stale_egg(obj)) {
@@ -1001,7 +1002,7 @@ int dieroll;
case BLINDING_VENOM:
mon->msleeping = 0;
if (can_blnd(&youmonst, mon,
(uchar) (obj->otyp == BLINDING_VENOM
(uchar) ((obj->otyp == BLINDING_VENOM)
? AT_SPIT
: AT_WEAP),
obj)) {
@@ -1309,7 +1310,9 @@ int dieroll;
if (unpoisonmsg)
Strcpy(saved_oname, cxname(obj));
/* [note: thrown obj might go away during killed/xkilled call] */
/* [note: thrown obj might go away during killed()/xkilled() call
(via 'thrownobj'; if swallowed, it gets added to engulfer's
minvent and might merge with a stack that's already there)] */
if (needpoismsg)
pline_The("poison doesn't seem to affect %s.", mon_nam(mon));