fix unnaming types of objects

docall() would access freed memory if the player used space(s) as
a fake object type name in order to remove an existing name without
giving any new one.

3.4.3 had this bug too; I didn't go farther back.
This commit is contained in:
PatR
2023-12-27 04:59:44 -08:00
parent 94b59cbd35
commit 97272d3627
2 changed files with 14 additions and 13 deletions

View File

@@ -1338,6 +1338,8 @@ amulet of unchanging cannot be polymorphed
wishing for a "lit candle" provided one, but the feedback as it was added into
invent was "partly used candle (lit)" because of how 'lit' timer works
don't fall off steed because of Fumbling if saddle is cursed
using <space(s)> to remove an existing name given to a type of object was
accessing freed memory
Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -1765,40 +1765,39 @@ void
docall(struct obj *obj)
{
char buf[BUFSZ], qbuf[QBUFSZ];
char **str1;
char **uname_p;
boolean had_name = FALSE;
if (!obj->dknown)
return; /* probably blind */
return; /* probably blind; Blind || Hallucination for 'fromsink' */
flush_screen(1); /* buffered updates might matter to player's response */
if (obj->oclass == POTION_CLASS && obj->fromsink)
/* kludge, meaning it's sink water */
/* fromsink: kludge, meaning it's sink water */
Sprintf(qbuf, "Call a stream of %s fluid:",
OBJ_DESCR(objects[obj->otyp]));
else
(void) safe_qbuf(qbuf, "Call ", ":", obj,
docall_xname, simpleonames, "thing");
/* pointer to old name */
str1 = &(objects[obj->otyp].oc_uname);
uname_p = &(objects[obj->otyp].oc_uname);
/* use getlin() to get a name string from the player */
if (!name_from_player(buf, qbuf, *str1))
if (!name_from_player(buf, qbuf, *uname_p))
return;
/* clear old name */
if (*str1)
free((genericptr_t) *str1);
if (*uname_p) {
had_name = TRUE;
free((genericptr_t) *uname_p), *uname_p = NULL; /* clear oc_uname */
}
/* strip leading and trailing spaces; uncalls item if all spaces */
(void) mungspaces(buf);
if (!*buf) {
if (*str1) { /* had name, so possibly remove from disco[] */
/* strip name first, for the update_inventory() call
from undiscover_object() */
*str1 = (char *) 0;
if (had_name) /* possibly remove from disco[]; old *uname_p is gone */
undiscover_object(obj->otyp);
}
} else {
*str1 = dupstr(buf);
*uname_p = dupstr(buf);
discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
}
}