prevent pline() segfault

The use of debugpline() in tty_curs() got me wondering what would
happen if debugpline() was called while pline() is in progress.  I
don't know how to trigger the bad coordinate situation, so I put an
unconditional debugpline() in the NHW_MESSAGE case of tty_putstr()
and used DEBUGFILES=wintty.c to enable it.  Instant segfault, and
the backtrace was short and not useful so the stack might have been
clobbered.  I didn't spend any time trying to figure where or why
the segfault occurred.

Change pline() so that if it is called while the previous pline()
hasn't finished yet (ie, recursively), use raw_print() and return
early.  The raw_print message isn't very useful--it pops up wherever
the cursor happens to be, just like the cursor position bug that has
been an issue recently--but does get delivered without any segualt
and isn't completely useless if DUMPLOG is enabled and you save or
quit before the message buffer gets recycled.  Message readability
situation could be improved but avoiding the segfault was my goal.

Putting any debugpline() into *_raw_print() would be inadvisable....
This commit is contained in:
PatR
2018-03-13 11:27:04 -07:00
parent 0b6e26d9e0
commit c28b44c27c
2 changed files with 15 additions and 5 deletions

View File

@@ -524,6 +524,8 @@ It shouldn't be considered hypocrisy if you speed up your pet while standing
fix 'object lost' panic if hero with lycanthropy but in human form is wielding
a potion of unholy water which gets boiled/exploded by fire, causing
were-transformation and drop of wielded weapon
prevent segfault if pline() is called recursively (which could happen if the
interface code issues a debugpline() while processing putstr())
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 pline.c $NHDT-Date: 1519183957 2018/02/21 03:32:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.65 $ */
/* NetHack 3.6 pline.c $NHDT-Date: 1520964541 2018/03/13 18:09:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.66 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -96,6 +96,7 @@ void pline
VA_DECL(const char *, line)
#endif /* USE_STDARG | USE_VARARG */
{ /* start of vpline() or of nested block in USE_OLDARG's pline() */
static int in_pline = 0;
char pbuf[3 * BUFSZ];
int ln;
int msgtyp;
@@ -138,11 +139,14 @@ VA_DECL(const char *, line)
if ((pline_flags & SUPPRESS_HISTORY) == 0)
dumplogmsg(line);
#endif
if (!iflags.window_inited) {
/* use raw_print() if we're called too early (or perhaps too late
during shutdown) or if we're being called recursively (probably
via debugpline() in the interface code) */
if (in_pline++ || !iflags.window_inited) {
/* [we should probably be using raw_printf("\n%s", line) here] */
raw_print(line);
iflags.last_msg = PLNMSG_UNKNOWN;
return;
goto pline_done;
}
msgtyp = MSGTYP_NORMAL;
@@ -158,7 +162,7 @@ VA_DECL(const char *, line)
* doing so out of context and probably end up seeming silly.
* (Not an issue for no-repeat but matters for no-show.)
*/
return;
goto pline_done;
}
if (vision_full_recalc)
@@ -178,6 +182,10 @@ VA_DECL(const char *, line)
if (msgtyp == MSGTYP_STOP)
display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */
pline_done:
--in_pline;
return;
#if !(defined(USE_STDARG) || defined(USE_VARARGS))
/* provide closing brace for the nested block
which immediately follows USE_OLDARGS's VA_DECL() */