fix segfault from splitting 1hp long worm

Fix the crash From a bug report, where
having the hit that cuts a long worm into two also take the original down
to 1 HP would result in clone_mon() returning null and nethack crashing due
to a segmentation fault or access violation.  The same thing could happen
if there's been enough long worms created to get them flagged as extinct.

     This bug was only present in 3.4.3.  Prior to that, cut_worm() did
its own monster creation inline instead of calling clone_mon(), ignoring
extinction and too-low hit points.
This commit is contained in:
nethack.rankin
2007-07-28 03:26:45 +00:00
parent aac603a446
commit 03eb70acab
2 changed files with 18 additions and 6 deletions

View File

@@ -361,6 +361,8 @@ monsters who want the Amulet won't attack the Wizard to try to get it
opening or closing the castle drawbridge via music consumes a turn
could get "suddenly you cannot see the <mon>" while invisible mon remained
displayed due to telepathy or extended detection
cutting a long worm in half would trigger segfault/accvio crash if the hit
took parent down to 1 hit point or if long worms had become extinct
Platform- and/or Interface-Specific Fixes

View File

@@ -366,19 +366,29 @@ cutworm(worm, x, y, weap)
* it's head at "curr" and its tail at "new_tail".
*/
new_worm = 0;
new_wnum = rn2(3) ? 0 : get_wormno();
if (new_wnum) {
remove_monster(x, y); /* clone_mon puts new head here */
/* clone_mon() will fail if enough long worms have been
created to have them be marked as extinct or if the hit
that cut the current one has dropped it down to 1 HP */
new_worm = clone_mon(worm, x, y);
}
/* Sometimes the tail end dies. */
if (rn2(3) || !(new_wnum = get_wormno())) {
if (context.mon_moving)
pline("Part of the tail of %s is cut off.", mon_nam(worm));
else
if (!new_worm) {
if (context.mon_moving) {
if (canspotmon(worm))
pline("Part of %s tail has been cut off.",
s_suffix(mon_nam(worm)));
} else
You("cut part of the tail off of %s.", mon_nam(worm));
toss_wsegs(new_tail, TRUE);
if (worm->mhp > 1) worm->mhp /= 2;
return;
}
remove_monster(x, y); /* clone_mon puts new head here */
new_worm = clone_mon(worm, x, y);
new_worm->wormno = new_wnum; /* affix new worm number */
new_worm->mcloned = 0; /* treat second worm as a normal monster */