avoid crash when thrown potion hits bars before a monster

From a bug report. <Someone> as slashem-Bugs-883643 on 1/24/2004.  To avoid
using the possibly invalid object pointer after calling bhit(), changed as
suggested to add another level of indirection allowing bhit to null the
object pointer before returning.  Callers that are affected update their
object pointers after bhit returns.
This commit is contained in:
cohrs
2005-06-21 18:51:48 +00:00
parent bd1af39997
commit b72967f6a6
6 changed files with 25 additions and 12 deletions
+1
View File
@@ -127,6 +127,7 @@ becoming green slime or mimicking gold violates "never changed form" conduct
when a monster grew into a higher form which had previously been genocided, when a monster grew into a higher form which had previously been genocided,
the message explaining its fate was only given if it was sensed via ESP the message explaining its fate was only given if it was sensed via ESP
hero could still see for brief period after being blinded by potion vapors hero could still see for brief period after being blinded by potion vapors
avoid crash when thrown potion hits bars before a monster
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+1 -1
View File
@@ -2467,7 +2467,7 @@ E const char *FDECL(exclam, (int force));
E void FDECL(hit, (const char *,struct monst *,const char *)); E void FDECL(hit, (const char *,struct monst *,const char *));
E void FDECL(miss, (const char *,struct monst *)); E void FDECL(miss, (const char *,struct monst *));
E struct monst *FDECL(bhit, (int,int,int,int,int (*)(MONST_P,OBJ_P), E struct monst *FDECL(bhit, (int,int,int,int,int (*)(MONST_P,OBJ_P),
int (*)(OBJ_P,OBJ_P),struct obj *)); int (*)(OBJ_P,OBJ_P),struct obj **));
E struct monst *FDECL(boomhit, (int,int)); E struct monst *FDECL(boomhit, (int,int));
E int FDECL(burn_floor_paper, (int,int,BOOLEAN_P,BOOLEAN_P)); E int FDECL(burn_floor_paper, (int,int,BOOLEAN_P,BOOLEAN_P));
E void FDECL(buzz, (int,int,XCHAR_P,XCHAR_P,int,int)); E void FDECL(buzz, (int,int,XCHAR_P,XCHAR_P,int,int));
+2 -2
View File
@@ -79,7 +79,7 @@ use_camera(obj)
} else if ((mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT, } else if ((mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,
(int FDECL((*),(MONST_P,OBJ_P)))0, (int FDECL((*),(MONST_P,OBJ_P)))0,
(int FDECL((*),(OBJ_P,OBJ_P)))0, (int FDECL((*),(OBJ_P,OBJ_P)))0,
obj)) != 0) { &obj)) != 0) {
obj->ox = u.ux, obj->oy = u.uy; obj->ox = u.ux, obj->oy = u.uy;
(void) flash_hits_mon(mtmp, obj); (void) flash_hits_mon(mtmp, obj);
} }
@@ -749,7 +749,7 @@ struct obj *obj;
mtmp = bhit(u.dx, u.dy, COLNO, INVIS_BEAM, mtmp = bhit(u.dx, u.dy, COLNO, INVIS_BEAM,
(int FDECL((*),(MONST_P,OBJ_P)))0, (int FDECL((*),(MONST_P,OBJ_P)))0,
(int FDECL((*),(OBJ_P,OBJ_P)))0, (int FDECL((*),(OBJ_P,OBJ_P)))0,
obj); &obj);
if (!mtmp || !haseyes(mtmp->data)) if (!mtmp || !haseyes(mtmp->data))
return 1; return 1;
+2 -1
View File
@@ -557,7 +557,8 @@ xchar x, y;
mon = bhit(u.dx, u.dy, range, KICKED_WEAPON, mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,
(int FDECL((*),(MONST_P,OBJ_P)))0, (int FDECL((*),(MONST_P,OBJ_P)))0,
(int FDECL((*),(OBJ_P,OBJ_P)))0, (int FDECL((*),(OBJ_P,OBJ_P)))0,
kickobj); &kickobj);
if (!kickobj) return 1; /* object broken */
if(mon) { if(mon) {
if (mon->isshk && if (mon->isshk &&
+8 -3
View File
@@ -873,9 +873,10 @@ struct obj *obj;
} }
} }
/* throw an object, NB: obj may be consumed in the process */
void void
throwit(obj, wep_mask, twoweap) throwit(obj, wep_mask, twoweap)
register struct obj *obj; struct obj *obj;
long wep_mask; /* used to re-equip returning boomerang */ long wep_mask; /* used to re-equip returning boomerang */
boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
{ {
@@ -1000,11 +1001,14 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
mon = bhit(u.dx, u.dy, range, THROWN_WEAPON, mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
(int FDECL((*),(MONST_P,OBJ_P)))0, (int FDECL((*),(MONST_P,OBJ_P)))0,
(int FDECL((*),(OBJ_P,OBJ_P)))0, (int FDECL((*),(OBJ_P,OBJ_P)))0,
obj); &obj);
thrownobj = obj; /* obj may be null now */
/* have to do this after bhit() so u.ux & u.uy are correct */ /* have to do this after bhit() so u.ux & u.uy are correct */
if(Is_airlevel(&u.uz) || Levitation) if(Is_airlevel(&u.uz) || Levitation)
hurtle(-u.dx, -u.dy, urange, TRUE); hurtle(-u.dx, -u.dy, urange, TRUE);
if (!obj) return;
} }
if (mon) { if (mon) {
@@ -1777,7 +1781,8 @@ struct obj *obj;
mon = bhit(u.dx, u.dy, range, THROWN_WEAPON, mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
(int FDECL((*),(MONST_P,OBJ_P)))0, (int FDECL((*),(MONST_P,OBJ_P)))0,
(int FDECL((*),(OBJ_P,OBJ_P)))0, (int FDECL((*),(OBJ_P,OBJ_P)))0,
obj); &obj);
if (!obj) return 1; /* object is gone */
if(mon) { if(mon) {
if (ghitm(mon, obj)) /* was it caught? */ if (ghitm(mon, obj)) /* was it caught? */
return 1; return 1;
+11 -5
View File
@@ -2465,7 +2465,7 @@ struct obj *obj; /* wand or spell */
/* called for various wand and spell effects - M. Stephenson */ /* called for various wand and spell effects - M. Stephenson */
void void
weffects(obj) weffects(obj)
register struct obj *obj; struct obj *obj;
{ {
int otyp = obj->otyp; int otyp = obj->otyp;
boolean disclose = FALSE, was_unkn = !objects[otyp].oc_name_known; boolean disclose = FALSE, was_unkn = !objects[otyp].oc_name_known;
@@ -2486,7 +2486,7 @@ register struct obj *obj;
} else if (u.dz) { } else if (u.dz) {
disclose = zap_updown(obj); disclose = zap_updown(obj);
} else { } else {
(void) bhit(u.dx,u.dy, rn1(8,6),ZAPPED_WAND, bhitm,bhito, obj); (void) bhit(u.dx,u.dy, rn1(8,6),ZAPPED_WAND, bhitm,bhito, &obj);
} }
/* give a clue if obj_zapped */ /* give a clue if obj_zapped */
if (obj_zapped) if (obj_zapped)
@@ -2634,20 +2634,25 @@ int range, *skipstart, *skipend;
* function) several objects and monsters on its path. The return value * function) several objects and monsters on its path. The return value
* is the monster hit (weapon != ZAPPED_WAND), or a null monster pointer. * is the monster hit (weapon != ZAPPED_WAND), or a null monster pointer.
* *
* Thrown and kicked objects (THROWN_WEAPON or KICKED_WEAPON) may be
* destroyed and *pobj set to NULL to indicate this.
*
* Check !u.uswallow before calling bhit(). * Check !u.uswallow before calling bhit().
* This function reveals the absence of a remembered invisible monster in * This function reveals the absence of a remembered invisible monster in
* necessary cases (throwing or kicking weapons). The presence of a real * necessary cases (throwing or kicking weapons). The presence of a real
* one is revealed for a weapon, but if not a weapon is left up to fhitm(). * one is revealed for a weapon, but if not a weapon is left up to fhitm().
*/ */
struct monst * struct monst *
bhit(ddx,ddy,range,weapon,fhitm,fhito,obj) bhit(ddx,ddy,range,weapon,fhitm,fhito,pobj)
register int ddx,ddy,range; /* direction and range */ register int ddx,ddy,range; /* direction and range */
int weapon; /* see values in hack.h */ int weapon; /* see values in hack.h */
int FDECL((*fhitm), (MONST_P, OBJ_P)), /* fns called when mon/obj hit */ int FDECL((*fhitm), (MONST_P, OBJ_P)), /* fns called when mon/obj hit */
FDECL((*fhito), (OBJ_P, OBJ_P)); FDECL((*fhito), (OBJ_P, OBJ_P));
struct obj *obj; /* object tossed/used */ struct obj **pobj; /* object tossed/used, set to NULL
* if object is destroyed */
{ {
struct monst *mtmp; struct monst *mtmp;
struct obj *obj = *pobj;
uchar typ; uchar typ;
boolean shopdoor = FALSE, point_blank = TRUE; boolean shopdoor = FALSE, point_blank = TRUE;
boolean in_skip = FALSE, allow_skip = FALSE; boolean in_skip = FALSE, allow_skip = FALSE;
@@ -2697,9 +2702,10 @@ struct obj *obj; /* object tossed/used */
/* iron bars will block anything big enough */ /* iron bars will block anything big enough */
if ((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) && if ((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) &&
typ == IRONBARS && typ == IRONBARS &&
hits_bars(&obj, x - ddx, y - ddy, hits_bars(pobj, x - ddx, y - ddy,
point_blank ? 0 : !rn2(5), 1)) { point_blank ? 0 : !rn2(5), 1)) {
/* caveat: obj might now be null... */ /* caveat: obj might now be null... */
obj = *pobj;
bhitpos.x -= ddx; bhitpos.x -= ddx;
bhitpos.y -= ddy; bhitpos.y -= ddy;
break; break;