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:
nethack.rankin
2006-11-03 07:13:27 +00:00
parent 8ead488b63
commit 672c14c0c5
2 changed files with 27 additions and 9 deletions
+3
View File
@@ -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 avoid drowned in a drowning and burned by burning if life-saving is inadequate
reveal hidden monsters who change levels or are magically summoned 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 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 Platform- and/or Interface-Specific Fixes
+24 -9
View File
@@ -822,13 +822,16 @@ register const char *let,*word;
if(bp > buf && bp[-1] == '-') *bp++ = ' '; if(bp > buf && bp[-1] == '-') *bp++ = ' ';
ap = altlets; ap = altlets;
ilet = 'a'; if (!flags.invlet_constant) reassign();
for (otmp = invent; otmp; otmp = otmp->nobj) { for (otmp = invent; otmp; otmp = otmp->nobj) {
if (!flags.invlet_constant) if (&bp[foo] == &buf[sizeof buf - 1] ||
#ifdef GOLDOBJ ap == &altlets[sizeof altlets - 1]) {
if (otmp->invlet != GOLD_SYM) /* don't reassign this */ /* we must have a huge number of NOINVSYM items somehow */
#endif impossible("getobj: inventory overflow");
otmp->invlet = ilet; /* reassign() */ break;
}
if (!*let || index(let, otmp->oclass) if (!*let || index(let, otmp->oclass)
#ifdef GOLDOBJ #ifdef GOLDOBJ
|| (usegold && otmp->invlet == GOLD_SYM) || (usegold && otmp->invlet == GOLD_SYM)
@@ -937,8 +940,6 @@ register const char *let,*word;
))) )))
allowall = TRUE; allowall = TRUE;
} }
if(ilet == 'z') ilet = 'A'; else ilet++;
} }
bp[foo] = 0; bp[foo] = 0;
if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
@@ -2742,8 +2743,22 @@ reassign()
register int i; register int i;
register struct obj *obj; 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); 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; lastinvnr = i;
} }