From 0f57f0e48ca6e6823fb238566d5faddd3cf0726b Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 11 Jul 2019 21:04:29 -0700 Subject: [PATCH] Fixed bug with inmore and toplin state management. When fuzzing, we would increment ttyDisplay->inmore but then prematurely exit more() leaving ttyDisplay->inmore set. Under various conditions, we can request to remember the topline when the topline had not yet been acknowledged leaving toplin state in an inappropriate state. --- win/tty/topl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/win/tty/topl.c b/win/tty/topl.c index d2a889cc9..bb79be26c 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -139,7 +139,7 @@ const char *str; putsyms(str); cl_end(); ttyDisplay->toplin = TOPLINE_NEED_MORE; - if (ttyDisplay->cury && otoplin != 3) + if (ttyDisplay->cury && otoplin != TOPLINE_SPECIAL_PROMPT) more(); } @@ -204,12 +204,15 @@ more() { struct WinDesc *cw = wins[WIN_MESSAGE]; - /* avoid recursion -- only happens from interrupts */ - if (ttyDisplay->inmore++) - return; if (iflags.debug_fuzzer) return; + /* avoid recursion -- only happens from interrupts */ + if (ttyDisplay->inmore) + return; + + ttyDisplay->inmore++; + if (ttyDisplay->toplin) { tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury); if (cw->curx >= CO - 8) @@ -256,6 +259,7 @@ register const char *bp; && cw->cury == 0 && n0 + (int) strlen(toplines) + 3 < CO - 8 /* room for --More-- */ && (notdied = strncmp(bp, "You die", 7)) != 0) { + nhassert(strlen(toplines) == cw->curx); Strcat(toplines, " "); Strcat(toplines, bp); cw->curx += 2; @@ -309,6 +313,7 @@ char c; if (ttyDisplay->curx == 0 && ttyDisplay->cury > 0) tty_curs(BASE_WINDOW, CO, (int) ttyDisplay->cury - 1); backsp(); + nhassert(ttyDisplay->curx > 0); ttyDisplay->curx--; cw->curx = ttyDisplay->curx; return; @@ -689,6 +694,13 @@ boolean restoring_msghist; } if (msg) { + /* Caller is asking us to remember a top line that needed more. + Should we call more? This can happen when the player has set + iflags.force_invmenu and they attempt to shoot with nothing in + the quiver. */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; + /* move most recent message to history, make this become most recent */ remember_topl(); Strcpy(toplines, msg); @@ -696,6 +708,9 @@ boolean restoring_msghist; dumplogmsg(toplines); #endif } else if (snapshot_mesgs) { + nhassert(ttyDisplay == NULL || + ttyDisplay->toplin != TOPLINE_NEED_MORE); + /* done putting arbitrary messages in; put the snapshot ones back */ for (idx = 0; snapshot_mesgs[idx]; ++idx) { remember_topl(); -- 2.49.0