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

@@ -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[] */
}
}