fix crash on NULL gi.invent

This commit is contained in:
nhmall
2024-01-31 12:51:33 -05:00
parent 95e42bf692
commit 378648bd9c
6 changed files with 29 additions and 27 deletions

View File

@@ -1239,7 +1239,7 @@ extern Loot *sortloot(struct obj **, unsigned, boolean,
boolean(*)(struct obj *)) NONNULLARG1;
extern void unsortloot(Loot **) NONNULLARG1;
extern void assigninvlet(struct obj *) NONNULLARG1;
extern struct obj *merge_choice(struct obj *, struct obj *) NONNULLPTRS;
extern struct obj *merge_choice(struct obj **, struct obj *) NONNULLPTRS;
extern int merged(struct obj **, struct obj **) NONNULLPTRS;
extern void addinv_core1(struct obj *) NONNULLARG1;
extern void addinv_core2(struct obj *) NONNULLARG1;

View File

@@ -3885,7 +3885,7 @@ wizkit_addinv(struct obj *obj)
obj->bknown = 1; /* ok to bypass set_bknown() */
/* same criteria as lift_object()'s check for available inventory slot */
if (obj->oclass != COIN_CLASS && inv_cnt(FALSE) >= invlet_basic
&& !merge_choice(gi.invent, obj)) {
&& !merge_choice(&gi.invent, obj)) {
/* inventory overflow; can't just place & stack object since
hero isn't in position yet, so schedule for arrival later */
add_to_migration(obj);

View File

@@ -781,10 +781,11 @@ reorder_invent(void)
one of them; used in pickup.c when all 52 inventory slots are in use,
to figure out whether another object could still be picked up */
struct obj *
merge_choice(struct obj *objlist, struct obj *obj)
merge_choice(struct obj **objlist, struct obj *obj)
{
struct monst *shkp;
unsigned save_nocharge;
struct obj *olist = *objlist;
if (obj->otyp == SCR_SCARE_MONSTER) /* punt on these */
return (struct obj *) 0;
@@ -792,28 +793,29 @@ merge_choice(struct obj *objlist, struct obj *obj)
have when carried are different from what they are now; prevent
that from eliciting an incorrect result from mergable() */
save_nocharge = obj->no_charge;
if (objlist == gi.invent && obj->where == OBJ_FLOOR
&& (shkp = shop_keeper(inside_shop(obj->ox, obj->oy))) != 0) {
if (obj->no_charge)
obj->no_charge = 0;
/* A billable object won't have its `unpaid' bit set, so would
erroneously seem to be a candidate to merge with a similar
ordinary object. That's no good, because once it's really
picked up, it won't merge after all. It might merge with
another unpaid object, but we can't check that here (depends
too much upon shk's bill) and if it doesn't merge it would
end up in the '#' overflow inventory slot, so reject it now. */
else if (inhishop(shkp))
return (struct obj *) 0;
if (olist) {
if (olist == gi.invent && obj->where == OBJ_FLOOR
&& (shkp = shop_keeper(inside_shop(obj->ox, obj->oy))) != 0) {
if (obj->no_charge)
obj->no_charge = 0;
/* A billable object won't have its `unpaid' bit set, so would
erroneously seem to be a candidate to merge with a similar
ordinary object. That's no good, because once it's really
picked up, it won't merge after all. It might merge with
another unpaid object, but we can't check that here (depends
too much upon shk's bill) and if it doesn't merge it would
end up in the '#' overflow inventory slot, so reject it now. */
else if (inhishop(shkp))
return (struct obj *) 0;
}
do {
if (mergable(olist, obj))
break;
olist = olist->nobj;
} while (olist);
}
do {
/*assert(objlist != NULL);*/
if (mergable(objlist, obj))
break;
objlist = objlist->nobj;
} while (objlist);
obj->no_charge = save_nocharge;
return objlist;
return olist;
}
/* merge obj with otmp and delete obj if types agree */

View File

@@ -1699,7 +1699,7 @@ lift_object(
if (obj->otyp == LOADSTONE
|| (obj->otyp == BOULDER && throws_rocks(gy.youmonst.data))) {
if (inv_cnt(FALSE) < invlet_basic || !carrying(obj->otyp)
|| merge_choice(gi.invent, obj))
|| merge_choice(&gi.invent, obj))
return 1; /* lift regardless of current situation */
/* if we reach here, we're out of slots and already have at least
one of these, so treat this one more like a normal item
@@ -1719,7 +1719,7 @@ lift_object(
/* [exception for gold coins will have to change
if silver/copper ones ever get implemented] */
&& inv_cnt(FALSE) >= invlet_basic
&& !merge_choice(gi.invent, obj)) {
&& !merge_choice(&gi.invent, obj)) {
/* if there is some gold here (and we haven't already skipped it),
we aren't limited by the 52 item limit for it, but caller and
"grandcaller" aren't prepared to skip stuff and then pickup

View File

@@ -152,7 +152,7 @@ money2u(struct monst* mon, long amount)
mongold = splitobj(mongold, amount);
obj_extract_self(mongold);
if (!merge_choice(gi.invent, mongold)
if (!merge_choice(&gi.invent, mongold)
&& inv_cnt(FALSE) >= invlet_basic) {
You("have no room for the gold!");
dropy(mongold);

View File

@@ -2717,7 +2717,7 @@ mhitm_ad_sgld(
if (mongold) {
obj_extract_self(mongold);
if (merge_choice(gi.invent, mongold)
if (merge_choice(&gi.invent, mongold)
|| inv_cnt(FALSE) < invlet_basic) {
addinv(mongold);
Your("purse feels heavier.");