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:
@@ -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
|
||||
|
||||
18
src/pline.c
18
src/pline.c
@@ -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() */
|
||||
|
||||
Reference in New Issue
Block a user