From 149139a25d76894bb1b9189ef8a96a544a7094e9 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 26 Jan 2016 17:32:05 -0800 Subject: [PATCH] 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 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. --- src/potion.c | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/potion.c b/src/potion.c index 484b89806..501998ba1 100644 --- a/src/potion.c +++ b/src/potion.c @@ -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 into? [xyz or ?*] " + */ + Strcpy(obuf, short_oname(obj, doname, thesimpleoname, + /* 128 - (24 + 54 + 1) leaves 49 for */ + 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 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 into the {pool, moat, &c}?" */ if (yn(qbuf) == 'y') { if (Levitation) { @@ -1801,20 +1809,9 @@ dodip() } } - /* "What do you want to dip 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 into" */ + /* "What do you want to dip 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) { -- 2.50.1