From 2bb73b8fd863f5aa9874e292dffffaf7d38f6d93 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 1 Mar 2023 16:20:43 -0500 Subject: [PATCH] Prevent curses 'More' (>>) from overwriting msg In some scenarios where a message prompted a 'more' (in curses shown as '>>'), the '>>' could overwrite the last one or two characters of the message. This could happen if a single message on its own was the length of the message space minus 2 (e.g. for an 80 character terminal, "h - a concave amulet named this is an amulet name, it is very long, and so on."), or if an addition to an existing line brought it to the length of the message space minus 1 or 2 (e.g. "You materialize on a different level! You remember this level as testlevlname."). The two scenarios had slightly different causes. I think this fixes both of those scenarios. I believe this is the cause of the problem described in GitHub issue #990 but there isn't enough detail to know that for a fact. --- win/curses/cursmesg.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index d1e82af49..0873f9b8d 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -105,9 +105,11 @@ curses_message_win_puts(const char *message, boolean recursed) mesg_add_line(message); } - /* -2: room for trailing ">>" (if More>> is needed) or leading " " - (if combining this message with preceding one) */ - linespace = (width - 1) - 2 - (mx - border_space); + /* -3: room for trailing ">> " (in case More>> is needed) */ + linespace = width - 3 - (mx - border_space); + /* -2: for leading " " (if combining this message with preceding one) */ + if (mx > border_space) + linespace -= 2; if (linespace < message_length) { if (my - border_space >= height - 1) { @@ -146,18 +148,18 @@ curses_message_win_puts(const char *message, boolean recursed) curses_toggle_color_attr(win, NONE, A_BOLD, ON); /* will this message fit as-is or do we need to split it? */ - if (mx == border_space && message_length > width - 2) { + if (mx == border_space && message_length > width - 3) { /* split needed */ - tmpstr = curses_break_str(message, (width - 2), 1); + tmpstr = curses_break_str(message, (width - 3), 1); mvwprintw(win, my, mx, "%s", tmpstr), mx += (int) strlen(tmpstr); /* one space to separate first part of message from rest [is this actually useful?] */ - if (mx < width - 2) + if (mx < width) ++mx; free(tmpstr); if (bold) curses_toggle_color_attr(win, NONE, A_BOLD, OFF); - tmpstr = curses_str_remainder(message, (width - 2), 1); + tmpstr = curses_str_remainder(message, (width - 3), 1); curses_message_win_puts(tmpstr, TRUE); free(tmpstr); } else {