fix #H3039 - panic() when trying to drop destroyed items
From a bug report, dropping a lit (burning) potion of oil while levitating can produce an explosion which can destroy inventory. If in the process of dropping multiple items, the ones after the oil might be gone, resulting in use of stale pointers and possibly triggering an "extract_nobj: object lost" panic or even a crash. While testing my fix, I discovered that being killed by an exploding potion of oil could produce an "object_is_local" panic if bones are saved (and reproduced with unmodified 3.4.3).
This commit is contained in:
29
src/worn.c
29
src/worn.c
@@ -673,6 +673,35 @@ struct obj *obj;
|
||||
context.bypasses = TRUE;
|
||||
}
|
||||
|
||||
/* set or clear the bypass bit in a list of objects */
|
||||
void
|
||||
bypass_objlist(objchain, on)
|
||||
struct obj *objchain;
|
||||
boolean on; /* TRUE => set, FALSE => clear */
|
||||
{
|
||||
if (on && objchain) context.bypasses = TRUE;
|
||||
while (objchain) {
|
||||
objchain->bypass = on ? 1 : 0;
|
||||
objchain = objchain->nobj;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the first object without its bypass bit set; set that bit
|
||||
before returning so that successive calls will find further objects */
|
||||
struct obj *
|
||||
nxt_unbypassed_obj(objchain)
|
||||
struct obj *objchain;
|
||||
{
|
||||
while (objchain) {
|
||||
if (!objchain->bypass) {
|
||||
bypass_obj(objchain);
|
||||
break;
|
||||
}
|
||||
objchain = objchain->nobj;
|
||||
}
|
||||
return objchain;
|
||||
}
|
||||
|
||||
void
|
||||
mon_break_armor(mon, polyspot)
|
||||
struct monst *mon;
|
||||
|
||||
Reference in New Issue
Block a user