more inventory overflow control
Prevent getobj() from overflowing its inventory letter collection
buffer if someone figures out some new way to fill up their inventory with
a huge number of # entries. Inventory manipulation might become crippled
at that stage but at least it shouldn't be able to trigger a crash.
Also, the !fixinv configuration was never taught about # and did
strange things if you had more than 52 items, both for inventory display
and object selection with getobj.
The reassign()/getobj() situation is definitely confused regarding
gold, using GOLD_SYM in some places and def_oc_syms[COIN_CLASS] in
others, and it's schizophrenic about whether the GOLDOBJ configuration
keeps gold in a letter slot or specially named $ slot. I'm sure there
are some problems there but I'm not planning to try to figure them out.
This commit is contained in:
@@ -265,6 +265,9 @@ fix invalid pointer dereference after applying a wielded cream pie
|
||||
avoid drowned in a drowning and burned by burning if life-saving is inadequate
|
||||
reveal hidden monsters who change levels or are magically summoned
|
||||
hero can't carry an unlimited number of boulders when poly'd into a giant
|
||||
prevent very large number of objects in # inventory slot from causing
|
||||
buffer overflow
|
||||
!fixinv config was using arbitrary characters instead of # for invent overflow
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
33
src/invent.c
33
src/invent.c
@@ -822,13 +822,16 @@ register const char *let,*word;
|
||||
if(bp > buf && bp[-1] == '-') *bp++ = ' ';
|
||||
ap = altlets;
|
||||
|
||||
ilet = 'a';
|
||||
if (!flags.invlet_constant) reassign();
|
||||
|
||||
for (otmp = invent; otmp; otmp = otmp->nobj) {
|
||||
if (!flags.invlet_constant)
|
||||
#ifdef GOLDOBJ
|
||||
if (otmp->invlet != GOLD_SYM) /* don't reassign this */
|
||||
#endif
|
||||
otmp->invlet = ilet; /* reassign() */
|
||||
if (&bp[foo] == &buf[sizeof buf - 1] ||
|
||||
ap == &altlets[sizeof altlets - 1]) {
|
||||
/* we must have a huge number of NOINVSYM items somehow */
|
||||
impossible("getobj: inventory overflow");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!*let || index(let, otmp->oclass)
|
||||
#ifdef GOLDOBJ
|
||||
|| (usegold && otmp->invlet == GOLD_SYM)
|
||||
@@ -937,8 +940,6 @@ register const char *let,*word;
|
||||
)))
|
||||
allowall = TRUE;
|
||||
}
|
||||
|
||||
if(ilet == 'z') ilet = 'A'; else ilet++;
|
||||
}
|
||||
bp[foo] = 0;
|
||||
if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
|
||||
@@ -2742,8 +2743,22 @@ reassign()
|
||||
register int i;
|
||||
register struct obj *obj;
|
||||
|
||||
for(obj = invent, i = 0; obj; obj = obj->nobj, i++)
|
||||
for(obj = invent, i = 0; obj; obj = obj->nobj, i++) {
|
||||
#ifdef GOLDOBJ
|
||||
if (obj->oclass == COIN_CLASS && obj->invlet == GOLD_SYM)
|
||||
--i; /* keep $ instead of using up i'th letter */
|
||||
else
|
||||
#endif
|
||||
if (i < 52)
|
||||
obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26);
|
||||
#ifdef GOLDOBJ
|
||||
else if (obj->oclass == COIN_CLASS)
|
||||
obj->invlet = GOLD_SYM;
|
||||
#endif
|
||||
else
|
||||
obj->invlet = NOINVSYM;
|
||||
}
|
||||
if (i >= 52) i = 52 - 1;
|
||||
lastinvnr = i;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user