shapechanger dropping boulders

Something I noticed while looking over the recent report about hug
attacks.  If a monster carrying one or more boulders (picked up while
in giant form) polymorphs into a non-giant, it will drop them.  If
that happens while it's trapped, it could be killed.  newcham() would
use a stale pointer to continue traversing its inventory after it was
dead and its possessions had been dropped.

I managed to get a chameleon-as-giant carrying boulders and some other
stuff trapped in a bear trap and then transform, but the few attempts
I made never killed off its next form so I wasn't able to induce a
crash to verify that a problem would actually occur.
This commit is contained in:
PatR
2023-04-12 03:03:17 -07:00
parent 8b32ae98e9
commit 9718181322
2 changed files with 18 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1146 $ $NHDT-Date: 1680935652 2023/04/08 06:34:12 $
HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1152 $ $NHDT-Date: 1681293789 2023/04/12 10:03:09 $
General Fixes and Modified Features
-----------------------------------
@@ -1135,6 +1135,10 @@ if hero had passes-walls capability and was at the location of a closed door,
attempting to use 'o' on own spot reported "you don't find anything
here to loot"; change to open door for '.' (or '<'), only loot for '>'
items thrown by monster landing on an altar did not show BUC flash
a chameleon in giant form who gets trapped (bear trap?) while carrying
boulders and changes shape could be killed when dropping them;
shape-change traversal of its inventory would continue after it
dropped everything, possibly resulting in a crash
Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 mon.c $NHDT-Date: 1679896593 2023/03/27 05:56:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.491 $ */
/* NetHack 3.7 mon.c $NHDT-Date: 1681293789 2023/04/12 10:03:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.494 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -4735,7 +4735,7 @@ newcham(
/* (this code used to try to adjust the monster's health based on
a normal one of its type but there are too many special cases
which need to handled in order to do that correctly, so just
which need to be handled in order to do that correctly, so just
give the new form the same proportion of HP as its old one had) */
hpn = mtmp->mhp;
hpd = mtmp->mhpmax;
@@ -4808,8 +4808,15 @@ newcham(
/* update swallow glyphs for new monster */
swallowed(0);
}
} else if (!sticks(mdat) && !sticks(gy.youmonst.data))
} else if ((!sticks(mdat) && !sticks(gy.youmonst.data))
/* sticky hero can't continue to hold mtmp if it has
turned into a non-solid creature; we don't use
uunstick() for that because its message would be
shown out of sequence [before 'if (msg)' below];
unstuck() doesn't issue any messages */
|| unsolid(mdat)) {
unstuck(mtmp);
}
}
if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) {
@@ -4856,7 +4863,9 @@ newcham(
if (mtmp->minvent && !throws_rocks(mdat)) {
register struct obj *otmp, *otmp2;
for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
/* DEADMONSTER(): it is possible for flooreffects() to kill mtmp;
the rest of its inventory would be dropped making otmp2 stale */
for (otmp = mtmp->minvent; otmp && !DEADMONSTER(mtmp); otmp = otmp2) {
otmp2 = otmp->nobj;
if (otmp->otyp == BOULDER) {
/* this keeps otmp from being polymorphed in the