fix #H6955 - wielded potion 'object lost' panic

Report classified this as 'segfault' but it's actually a controlled
panic().  When hero has lycanthropy and is wielding a potion of unholy
water while in human form, if that potion is boiled then it triggers
a transformation to beast form which in turn causes wielded weapon to
be dropped.  When the code unwinds back up through potionbreathe() to
destroy_item(), the boiled potion won't be found in inventory any more
and useup() -> useupall() -> freeinv() -> extract_nobj() panics.
This commit is contained in:
PatR
2018-03-11 12:39:01 -07:00
parent f026e37573
commit 152d9e7705
3 changed files with 24 additions and 7 deletions

View File

@@ -521,6 +521,9 @@ prayer boon of 'fix all troubles' could get stuck in an infinite loop for
TROUBLE_STUCK_IN_WALL if there was no spot to teleport into available
It shouldn't be considered hypocrisy if you speed up your pet while standing
on Elbereth
fix 'object lost' panic if hero with lycanthropy but in human form is wielding
a potion of unholy water which gets boiled/exploded by fire, causing
were-transformation and drop of wielded weapon
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 polyself.c $NHDT-Date: 1513298347 2017/12/15 00:39:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */
/* NetHack 3.6 polyself.c $NHDT-Date: 1520797126 2018/03/11 19:38:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.117 $ */
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
@@ -964,7 +964,7 @@ int alone;
{
struct obj *otmp;
const char *what, *which, *whichtoo;
boolean candropwep, candropswapwep;
boolean candropwep, candropswapwep, updateinv = TRUE;
if (uwep) {
/* !alone check below is currently superfluous but in the
@@ -989,17 +989,26 @@ int alone;
You("find you must %s %s %s!", what,
the_your[!!strncmp(which, "corpse", 6)], which);
}
/* if either uwep or wielded uswapwep is flagged as 'in_use'
then don't drop it or explicitly update inventory; leave
those actions to caller (or caller's caller, &c) */
if (u.twoweap) {
otmp = uswapwep;
uswapwepgone();
if (candropswapwep)
if (otmp->in_use)
updateinv = FALSE;
else if (candropswapwep)
dropx(otmp);
}
otmp = uwep;
uwepgone();
if (candropwep)
if (otmp->in_use)
updateinv = FALSE;
else if (candropwep)
dropx(otmp);
update_inventory();
if (updateinv)
update_inventory();
} else if (!could_twoweap(youmonst.data)) {
untwoweapon();
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 potion.c $NHDT-Date: 1502753790 2017/08/14 23:36:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.138 $ */
/* NetHack 3.6 potion.c $NHDT-Date: 1520797133 2018/03/11 19:38:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.144 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1563,6 +1563,11 @@ register struct obj *obj;
int i, ii, isdone, kn = 0;
boolean cureblind = FALSE;
/* potion of unholy water might be wielded; prevent
you_were() -> drop_weapon() from dropping it so that it
remains in inventory where our caller expects it to be */
obj->in_use = 1;
switch (obj->otyp) {
case POT_RESTORE_ABILITY:
case POT_GAIN_ABILITY:
@@ -1714,7 +1719,7 @@ register struct obj *obj;
break;
*/
}
/* note: no obfree() */
/* note: no obfree() -- that's our caller's responsibility */
if (obj->dknown) {
if (kn)
makeknown(obj->otyp);