]> granicus.if.org Git - nethack/commitdiff
yn_function (trunk only)
authornethack.rankin <nethack.rankin>
Sun, 22 Oct 2006 05:58:17 +0000 (05:58 +0000)
committernethack.rankin <nethack.rankin>
Sun, 22 Oct 2006 05:58:17 +0000 (05:58 +0000)
     Explicitly truncate the query prompt string to QBUFSZ-1 characters.
For tty and Amiga, no longer include the choices and default within that
length limit; use a bigger buffer to hold them along with the prompt.
-----

     While trying to eliminate the "Query truncated" entries present in
nethack.alt.org's paniclog, I seem to keep going backwards.  Allowing
<win>_yn_function() to accept a full QBUFSZ worth of characters will
simplify the existing yn_function() in the core and greatly simplify the
revised safe_qbuf() I've been working on.

     Some interfaces don't seem to care how long the prompt string is; I've
left those along.  Several of the others already copied the prompt string
into a BUFSZ sized buffer instead of a QBUFSZ sized one, making them
unlikely to suffer from buffer overflows.  This changes the rest (just tty
and Amiga, I think) to do the same.  Also for all that have any size
constraint, it now truncates the prompt query to QBUFSZ-1 chars as it is
used rather than continue to rely on the caller doing so.  This assumes
that appending the set of acceptable choices and the default response won't
overflow, which is a safe assumption unless/until QBUFSZ gets enlarged til
it's too close to BUFSZ.

     Only tty's topl.c has been tested.  The others should work ok, but
might possibly be bitten by a typo or two.  Qt's implementation of the X11
"slow" method (reusing a persistant one-line window for prompts) has been
handled, but its C++ class-based variant is untouched; NetHackQtYnDialog::
Exec() is completely baffling to me but doesn't appear to have any length
issues.

doc/window.doc
src/cmd.c

index 5e7bc1449d7c9ce2b235d9f1ffffcd33f2f014de..7694cd641bcf0375f05143ec559986e97682c03d 100644 (file)
@@ -215,6 +215,7 @@ char yn_function(const char *ques, const char *choices, char default)
                   returned, preserving case (upper or lower.) This means that
                   if the calling function needs an exact match, it must handle
                   user input correctness itself.
+               -- ques should not be more than QBUFSZ-1 characters long.
 getlin(const char *ques, char *input)
                -- Prints ques as a prompt and reads a single line of text,
                   up to a newline.  The string entered is returned without the
index df31aca03efbd1fa2fc909746387177266cda87c..9d5588e7313c617db72e3ede0a10cb9cbe4c0122 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -2947,22 +2947,20 @@ wiz_port_debug()
  *   window port causing a buffer overflow there.
  */
 char
-yn_function(query,resp, def)
-const char *query,*resp;
+yn_function(query, resp, def)
+const char *query, *resp;
 char def;
 {
        char qbuf[QBUFSZ];
-       unsigned truncspot, reduction = sizeof(" [N]  ?") + 1;
 
-       if (resp) reduction += strlen(resp) + sizeof(" () ");
-       if (strlen(query) < (QBUFSZ - reduction))
+       /* maximum acceptable length is QBUFSZ-1 */
+       if (strlen(query) < QBUFSZ)
                return (*windowprocs.win_yn_function)(query, resp, def);
+
+       /* caller shouldn't have passed anything this long */
        paniclog("Query truncated: ", query);
-       reduction += sizeof("...");
-       truncspot = QBUFSZ - reduction;
-       (void) strncpy(qbuf, query, (int)truncspot);
-       qbuf[truncspot] = '\0';
-       Strcat(qbuf,"...");
+       (void) strncpy(qbuf, query, QBUFSZ-1 - 3);
+       Strcpy(&qbuf[QBUFSZ-1 - 3], "...");
        return (*windowprocs.win_yn_function)(qbuf, resp, def);
 }