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.
This commit is contained in:
Bart House
2020-10-19 15:59:01 -07:00
parent 362fd6ffbf
commit aee1509979
+19 -4
View File
@@ -139,7 +139,7 @@ const char *str;
putsyms(str); putsyms(str);
cl_end(); cl_end();
ttyDisplay->toplin = TOPLINE_NEED_MORE; ttyDisplay->toplin = TOPLINE_NEED_MORE;
if (ttyDisplay->cury && otoplin != 3) if (ttyDisplay->cury && otoplin != TOPLINE_SPECIAL_PROMPT)
more(); more();
} }
@@ -204,12 +204,15 @@ more()
{ {
struct WinDesc *cw = wins[WIN_MESSAGE]; struct WinDesc *cw = wins[WIN_MESSAGE];
/* avoid recursion -- only happens from interrupts */
if (ttyDisplay->inmore++)
return;
if (iflags.debug_fuzzer) if (iflags.debug_fuzzer)
return; return;
/* avoid recursion -- only happens from interrupts */
if (ttyDisplay->inmore)
return;
ttyDisplay->inmore++;
if (ttyDisplay->toplin) { if (ttyDisplay->toplin) {
tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury); tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury);
if (cw->curx >= CO - 8) if (cw->curx >= CO - 8)
@@ -256,6 +259,7 @@ register const char *bp;
&& cw->cury == 0 && cw->cury == 0
&& n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */ && n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */
&& (notdied = strncmp(bp, "You die", 7)) != 0) { && (notdied = strncmp(bp, "You die", 7)) != 0) {
nhassert(strlen(g.toplines) == cw->curx);
Strcat(g.toplines, " "); Strcat(g.toplines, " ");
Strcat(g.toplines, bp); Strcat(g.toplines, bp);
cw->curx += 2; cw->curx += 2;
@@ -309,6 +313,7 @@ char c;
if (ttyDisplay->curx == 0 && ttyDisplay->cury > 0) if (ttyDisplay->curx == 0 && ttyDisplay->cury > 0)
tty_curs(BASE_WINDOW, CO, (int) ttyDisplay->cury - 1); tty_curs(BASE_WINDOW, CO, (int) ttyDisplay->cury - 1);
backsp(); backsp();
nhassert(ttyDisplay->curx > 0);
ttyDisplay->curx--; ttyDisplay->curx--;
cw->curx = ttyDisplay->curx; cw->curx = ttyDisplay->curx;
return; return;
@@ -686,6 +691,13 @@ boolean restoring_msghist;
} }
if (msg) { 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 */ /* move most recent message to history, make this become most recent */
remember_topl(); remember_topl();
Strcpy(g.toplines, msg); Strcpy(g.toplines, msg);
@@ -693,6 +705,9 @@ boolean restoring_msghist;
dumplogmsg(g.toplines); dumplogmsg(g.toplines);
#endif #endif
} else if (snapshot_mesgs) { } else if (snapshot_mesgs) {
nhassert(ttyDisplay == NULL ||
ttyDisplay->toplin != TOPLINE_NEED_MORE);
/* done putting arbitrary messages in; put the snapshot ones back */ /* done putting arbitrary messages in; put the snapshot ones back */
for (idx = 0; snapshot_mesgs[idx]; ++idx) { for (idx = 0; snapshot_mesgs[idx]; ++idx) {
remember_topl(); remember_topl();