From 3dc97916853f04d4332aaa37cdc9800060114351 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sun, 22 Oct 2006 05:58:17 +0000 Subject: [PATCH] yn_function (trunk only) 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 _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 | 1 + src/cmd.c | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/doc/window.doc b/doc/window.doc index 5e7bc1449..7694cd641 100644 --- a/doc/window.doc +++ b/doc/window.doc @@ -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 diff --git a/src/cmd.c b/src/cmd.c index df31aca03..9d5588e73 100644 --- 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); } -- 2.40.0