prompting for #dip

I noticed that my paniclog had a "Query truncated" entry from testing
the post-3.6.0 changes to #dip prompting.  For
"What do you want to dip <the object> into? [xyz or ?*] "
the use of safe_qbuf() didn't account for getobj() appending the list
of choices, so wasn't ensuring that the formatted object name combined
with the other text couldn't overflow QBUFSZ.

I had a more elaborate fix than this that still used safe_qbuf(), but
the extra complexity just wasn't worth it.  This potentially truncates
the formatted object description more severely than necessary but is
simple enough to be comprehensible.

No fixes36.1 entry.  This is updating a post-3.6.0 revision.
This commit is contained in:
PatR
2016-01-26 17:32:05 -08:00
parent 489445da02
commit 149139a25d

View File

@@ -1750,7 +1750,7 @@ dodip()
uchar here;
char allowall[2];
short mixture;
char qbuf[QBUFSZ], qtoo[QBUFSZ];
char qbuf[QBUFSZ], obuf[QBUFSZ];
const char *shortestname; /* last resort obj name for prompt */
allowall[0] = ALL_CLASSES;
@@ -1761,15 +1761,26 @@ dodip()
return 0;
shortestname = is_plural(obj) ? "them" : "it";
/*
* Bypass safe_qbuf() since it doesn't handle varying suffix without
* an awful lot of support work. Format the object once, even though
* the fountain and pool prompts offer a lot more room for it.
* 3.6.0 used thesimpleoname() unconditionally, which posed no risk
* of buffer overflow but drew bug reports because it omits user-
* supplied type name.
* getobj: "What do you want to dip <the object> into? [xyz or ?*] "
*/
Strcpy(obuf, short_oname(obj, doname, thesimpleoname,
/* 128 - (24 + 54 + 1) leaves 49 for <object> */
QBUFSZ - sizeof "What do you want to dip \
into? [abdeghjkmnpqstvwyzBCEFHIKLNOQRTUWXZ#-# or ?*] "));
here = levl[u.ux][u.uy].typ;
/* Is there a fountain to dip into here? */
if (IS_FOUNTAIN(here)) {
Sprintf(qtoo, into_the_something, "fountain");
if (flags.verbose)
(void) safe_qbuf(qbuf, Dip_, qtoo, obj,
doname, thesimpleoname, shortestname);
else
Sprintf(qbuf, "%s%s%s", Dip_, shortestname, qtoo);
Sprintf(qbuf, "%s%s%s%s", Dip_,
flags.verbose ? obuf : shortestname,
into_the_something, "fountain");
/* "Dip <the object> into the fountain?" */
if (yn(qbuf) == 'y') {
dipfountain(obj);
@@ -1778,12 +1789,9 @@ dodip()
} else if (is_pool(u.ux, u.uy)) {
const char *pooltype = waterbody_name(u.ux, u.uy);
Sprintf(qtoo, into_the_something, pooltype);
if (flags.verbose)
(void) safe_qbuf(qbuf, Dip_, qtoo, obj,
doname, thesimpleoname, shortestname);
else
Sprintf(qbuf, "%s%s%s", Dip_, shortestname, qtoo);
Sprintf(qbuf, "%s%s%s%s", Dip_,
flags.verbose ? obuf : shortestname,
into_the_something, pooltype);
/* "Dip <the object> into the {pool, moat, &c}?" */
if (yn(qbuf) == 'y') {
if (Levitation) {
@@ -1801,20 +1809,9 @@ dodip()
}
}
/* "What do you want to dip <the object> into?" */
if (flags.verbose) {
/* "What do you want to " is getobj()'s prefix, "dip " is ours */
Strcpy(qbuf, safe_qbuf(qtoo, "What do you want to dip ", " into?",
obj, doname, thesimpleoname, shortestname)
/* skip getobj()'s prefix when assigning to qbuf */
+ sizeof "What do you want to " - sizeof "");
/* we needed the '?' in " into?" so that safe_qbuf() was working
with the right overall length, but now we need to take the '?'
off because getobj() is going to append one */
*(eos(qbuf) - 1) = '\0';
} else
Sprintf(qbuf, "dip %s into", shortestname);
potion = getobj(beverages, qbuf); /* qbuf[] == "dip <obj> into" */
/* "What do you want to dip <the object> into? [xyz or ?*] " */
Sprintf(qbuf, "dip %s into", flags.verbose ? obuf : shortestname);
potion = getobj(beverages, qbuf);
if (!potion)
return 0;
if (potion == obj && potion->quan == 1L) {