fix pull request #621 - potential divide by 0
The pull request by argrath changes weight_cap() to never return a value less than 1 because try_lift() divides by that return value and a 0 would trigger a crash. The code involved is used when attempting to pull a monster out of a pit via #untrap. I'm fairly sure that weight_cap() can never produce a value that's less than 1 already, but have put in a variation of the PR's fix. I've also implemented a different fix that removes the division from try_lift(). The original code seems to have gone out of its way to avoid calculating inv_weight() twice, but doing the latter (for the once in a hundred games where it might happen) greatly simplifies things by removing details of carrying capacity. Fixes #621
This commit is contained in:
@@ -660,6 +660,8 @@ using 'F'orcefight against iron bars while wielding something breakable could
|
|||||||
called twice and could yield results that conflicted
|
called twice and could yield results that conflicted
|
||||||
have applying a polearm give feedback similar to 'F' for melee weapon when
|
have applying a polearm give feedback similar to 'F' for melee weapon when
|
||||||
attacking a wall or boulder
|
attacking a wall or boulder
|
||||||
|
if weight_cap() ever returned 0 (which probably can't happen), using #untrap
|
||||||
|
to pull a monster out of a pit would trigger a divide by 0 crash
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
+1
-3
@@ -3330,8 +3330,6 @@ weight_cap(void)
|
|||||||
if (EWounded_legs & RIGHT_SIDE)
|
if (EWounded_legs & RIGHT_SIDE)
|
||||||
carrcap -= 100;
|
carrcap -= 100;
|
||||||
}
|
}
|
||||||
if (carrcap < 0)
|
|
||||||
carrcap = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ELevitation != save_ELev || BLevitation != save_BLev) {
|
if (ELevitation != save_ELev || BLevitation != save_BLev) {
|
||||||
@@ -3340,7 +3338,7 @@ weight_cap(void)
|
|||||||
float_vs_flight();
|
float_vs_flight();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) carrcap;
|
return (int) max(carrcap, 1L); /* never return 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns how far beyond the normal capacity the player is currently. */
|
/* returns how far beyond the normal capacity the player is currently. */
|
||||||
|
|||||||
+17
-17
@@ -4687,18 +4687,15 @@ disarm_shooting_trap(struct trap* ttmp, int otyp)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the weight too heavy?
|
/* trying to #untrap a monster from a pit; is the weight too heavy? */
|
||||||
* Formula as in near_capacity() & check_capacity() */
|
|
||||||
static int
|
static int
|
||||||
try_lift(
|
try_lift(
|
||||||
struct monst *mtmp,
|
struct monst *mtmp, /* trapped monster */
|
||||||
struct trap *ttmp,
|
struct trap *ttmp, /* pit, possibly made by hero, or spiked pit */
|
||||||
int wt,
|
int xtra_wt, /* monster (corpse weight) + (stuff ? minvent weight : 0) */
|
||||||
boolean stuff)
|
boolean stuff) /* False: monster w/o minvent; True: w/ minvent */
|
||||||
{
|
{
|
||||||
int wc = weight_cap();
|
if (calc_capacity(xtra_wt) >= HVY_ENCUMBER) {
|
||||||
|
|
||||||
if (((wt * 2) / wc) >= HVY_ENCUMBER) {
|
|
||||||
pline("%s is %s for you to lift.", Monnam(mtmp),
|
pline("%s is %s for you to lift.", Monnam(mtmp),
|
||||||
stuff ? "carrying too much" : "too heavy");
|
stuff ? "carrying too much" : "too heavy");
|
||||||
if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
|
if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
|
||||||
@@ -4719,7 +4716,7 @@ help_monster_out(
|
|||||||
struct monst *mtmp,
|
struct monst *mtmp,
|
||||||
struct trap *ttmp)
|
struct trap *ttmp)
|
||||||
{
|
{
|
||||||
int wt;
|
int xtra_wt;
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
boolean uprob;
|
boolean uprob;
|
||||||
|
|
||||||
@@ -4788,15 +4785,18 @@ help_monster_out(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* is the monster too heavy? */
|
/* is the monster too heavy? */
|
||||||
wt = inv_weight() + mtmp->data->cwt;
|
xtra_wt = mtmp->data->cwt;
|
||||||
if (!try_lift(mtmp, ttmp, wt, FALSE))
|
if (!try_lift(mtmp, ttmp, xtra_wt, FALSE))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* is the monster with inventory too heavy? */
|
/* monster without its inventory isn't too heavy; if it carries
|
||||||
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
|
anything, include that minvent weight and check again */
|
||||||
wt += otmp->owt;
|
if (mtmp->minvent) {
|
||||||
if (!try_lift(mtmp, ttmp, wt, TRUE))
|
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
|
||||||
return 1;
|
xtra_wt += otmp->owt;
|
||||||
|
if (!try_lift(mtmp, ttmp, xtra_wt, TRUE))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
You("pull %s out of the pit.", mon_nam(mtmp));
|
You("pull %s out of the pit.", mon_nam(mtmp));
|
||||||
mtmp->mtrapped = 0;
|
mtmp->mtrapped = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user