From: PatR Date: Wed, 27 Jan 2016 01:32:05 +0000 (-0800) Subject: prompting for #dip X-Git-Tag: NetHack-3.6.1_RC01~982 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=149139a25d76894bb1b9189ef8a96a544a7094e9;p=nethack 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. --- 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) {