From d834ebb0ec1ea3e8c6a7399ab7d3af3cf99d784c Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 26 Oct 2019 19:01:49 -0700 Subject: [PATCH] paranoid_query bulletproofing Make paranoid_query() (yn question requiring explicit "yes" answer) protect itself from overly long prompt strings. I'm not aware of any specific overflowing queries so I temporary reduced QBUFSZ within paranoid_query() in order to test. For EDIT_GETLIN, don't use previous response as default if we loop after neither "yes" nor "no" was given for paranoid confirm. --- doc/fixes36.3 | 4 +++- src/cmd.c | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 3b9997702..1f8077ee2 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.147 $ $NHDT-Date: 1572070254 2019/10/26 06:10:54 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.149 $ $NHDT-Date: 1572141706 2019/10/27 02:01:46 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -255,6 +255,8 @@ EDIT_GETLIN: when naming an object or a monster use the existing name, if EDIT_GETLIN: using 'O' to set message types or menu colors was overloading the answer buffer with other stuff, resulting in bogus default response during repeat prompting +EDIT_GETLIN: for paranoid confirmation, if answer was neither "yes" nor "no", + don't supply the rejected answer as the default when retrying curses: very tall menus tried to use selector characters a-z, A-Z, and 0-9, but 0-9 should be reserved for counts and if the display was tall enough for more than 62 entries, arbitrary ASCII punctuation got used diff --git a/src/cmd.c b/src/cmd.c index e739172d5..0d65bb022 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1565574994 2019/08/12 01:56:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.343 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1572141702 2019/10/27 02:01:42 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.347 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6045,19 +6045,27 @@ const char *prompt; to give the go-ahead for this query; default is "no" unless the ParanoidConfirm flag is set in which case there's no default */ if (be_paranoid) { - char qbuf[QBUFSZ], ans[BUFSZ] = DUMMY; - const char *promptprefix = "", *responsetype = ParanoidConfirm - ? "(yes|no)" - : "(yes) [no]"; - int trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */ + char pbuf[BUFSZ], qbuf[QBUFSZ], ans[BUFSZ]; + const char *promptprefix = "", + *responsetype = ParanoidConfirm ? "(yes|no)" : "(yes) [no]"; + int k, trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */ + copynchars(pbuf, prompt, BUFSZ - 1); /* in addition to being paranoid about this particular query, we might be even more paranoid about all paranoia responses (ie, ParanoidConfirm is set) in which case we require "no" to reject in addition to "yes" to confirm (except we won't loop if response is ESC; it means no) */ do { - Sprintf(qbuf, "%s%s %s", promptprefix, prompt, responsetype); + /* make sure we won't overflow a QBUFSZ sized buffer */ + k = (int) (strlen(promptprefix) + 1 + strlen(responsetype)); + if ((int) strlen(pbuf) + k > QBUFSZ - 1) { + /* chop off some at the end */ + Strcpy(pbuf + (QBUFSZ - 1) - k - 4, "...?"); /* -4: "...?" */ + } + + Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype); + *ans = '\0'; getlin(qbuf, ans); (void) mungspaces(ans); confirmed_ok = !strcmpi(ans, "yes");