From 86df94b281dc02c2018735f84c8c25f88f82913e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 12 Dec 2016 17:42:02 +0200 Subject: [PATCH 1/5] Impossible instead of segfault in cursed While fuzz testing, I've seen segfault a handful of times in here, coming from do_takeoff(). Looks like context.takeoff.what is stale, having WORN_BLINDF, but we're not wearing the blindfold anymore. Haven't been able to trace it down yet, so guard it with impossible. --- src/do_wear.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/do_wear.c b/src/do_wear.c index e588e5413..15f00bbee 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1484,6 +1484,10 @@ int cursed(otmp) register struct obj *otmp; { + if (!otmp) { + impossible("cursed without otmp"); + return 0; + } /* Curses, like chickens, come home to roost. */ if ((otmp == uwep) ? welded(otmp) : (int) otmp->cursed) { boolean use_plural = (is_boots(otmp) || is_gloves(otmp) From f3b1cc74c6eccda4d2f20662b05ec2a80fd15054 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 14 Dec 2016 16:45:06 +0200 Subject: [PATCH 2/5] Set max players in sysconf, not in the shell script --- sys/unix/nethack.sh | 11 +---------- sys/unix/unixmain.c | 8 ++++++-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/sys/unix/nethack.sh b/sys/unix/nethack.sh index 47d0da861..eec1991d6 100755 --- a/sys/unix/nethack.sh +++ b/sys/unix/nethack.sh @@ -4,8 +4,6 @@ HACKDIR=/usr/games/lib/nethackdir export HACKDIR HACK=$HACKDIR/nethack -# NB: MAXNROFPLAYERS is deprecated in favor of MAXPLAYERS in SYSCF. -MAXNROFPLAYERS=4 # Since Nethack.ad is installed in HACKDIR, add it to XUSERFILESEARCHPATH case "x$XUSERFILESEARCHPATH" in @@ -65,11 +63,4 @@ fi cd $HACKDIR -case $1 in - -s*) - exec $HACK "$@" - ;; - *) - exec $HACK "$@" $MAXNROFPLAYERS - ;; -esac +exec $HACK "$@" diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 2d6452ce8..1c0d55f90 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -419,10 +419,14 @@ char *argv[]; } } - /* XXX This is deprecated in favor of SYSCF with MAXPLAYERS. Make - * an error in next release. */ +#ifdef SYSCF + if (argc > 1) + raw_printf("MAXPLAYERS are set in sysconf file.\n"); +#else + /* XXX This is deprecated in favor of SYSCF with MAXPLAYERS */ if (argc > 1) locknum = atoi(argv[1]); +#endif #ifdef MAX_NR_OF_PLAYERS /* limit to compile-time limit */ if (!locknum || locknum > MAX_NR_OF_PLAYERS) From f4632732ac9422ebd70e05c29d276513d949dcfb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 14 Dec 2016 18:27:57 +0200 Subject: [PATCH 3/5] Fix wishing for tins of specific type I believe this bug already existed, but was only exposed by my wishing parser change post-3.6.0 --- src/objnam.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index 7a800d23a..af3cc2511 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -2839,11 +2839,12 @@ struct obj *no_wish; */ if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ") && !strstri(bp, "finger ")) { - if (((p = strstri(bp, "tin of ")) != 0) - && (tmp = tin_variety_txt(p + 7, &tinv)) - && (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) { - *(p + 3) = 0; + if ((p = strstri(bp, "tin of ")) != 0) { + tmp = tin_variety_txt(p + 7, &tinv); tvariety = tinv; + mntmp = name_to_mon(p + 7 + tmp); + typ = TIN; + goto typfnd; } else if ((p = strstri(bp, " of ")) != 0 && (mntmp = name_to_mon(p + 4)) >= LOW_PM) *p = 0; From d606b2a8fff94afa21bae57bd0045b409136b72d Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 20 Dec 2016 12:43:35 -0800 Subject: [PATCH 4/5] tty's compress_str(), core's dat/keyhelp Rewrite 3.6.1's compress_str() to avoid peeking past the end of the input string. This should eliminate the reported valgrind complaint. The problem was noticed for post-3.6.0 code introduced [by me...] last June, but it looks like it was present in the old code too. Also, fix the wording in the paragraph about NUL in the keyhelp text. tty_putstr() always passes non-message window text through compress_str(), clobbering usage of two spaces to separate sentences. putstr()'s caller ought to have more control over that (possibly via its hardly ever used 'attribute' arg?). --- dat/keyhelp | 12 ++++++------ win/tty/wintty.c | 27 +++++++++++++++------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/dat/keyhelp b/dat/keyhelp index 41ab37ef1..d4df8d444 100644 --- a/dat/keyhelp +++ b/dat/keyhelp @@ -14,12 +14,12 @@ is reporting the wrong character but will be operating correctly if it describes ^J when you type ^M. - A NUL character, typed as ^ on some keyboards, ^@ on others, - and maybe not typeable at all on yet others. It is not used as a - command, and will be converted into ESC before reaching 'whatdoes'. - Unlike ^M, this transformation is performed by NetHack itself. - But like ^M, if you type NUL and get feedback about ESC, the - situation is expected. + A NUL character, which is typed as ^ on some keyboards, + ^@ on others, and maybe not typeable at all on yet others, is not + used as a command, and will be converted into ESC before reaching + 'whatdoes'. Unlike ^M, this transformation is performed within + NetHack. But like ^M, if you type NUL and get feedback about ESC, + the situation is expected. ESC itself is a synonym for ^[, and is another source of oddity. Various function keys, including cursor arrow keys, may transmit diff --git a/win/tty/wintty.c b/win/tty/wintty.c index e38e3e7c8..adec33c22 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -2448,19 +2448,22 @@ const char *str; topline wrapping converts space at wrap point into newline, we reverse that here */ if ((int) strlen(str) >= CO || index(str, '\n')) { - register const char *bp0 = str; - char c, nxtc, *bp1 = cbuf, *endbp1 = &cbuf[sizeof cbuf - 1]; + const char *in_str = str; + char c, *outstr = cbuf, *outend = &cbuf[sizeof cbuf - 1]; + boolean was_space = TRUE; /* True discards all leading spaces; + False would retain one if present */ - cbuf[0] = cbuf[sizeof cbuf - 1] = '\0'; /* superfluous */ - nxtc = (*bp0 == '\n') ? ' ' : *bp0; - do { - c = nxtc; - nxtc = bp0[1]; - if (nxtc == '\n') - nxtc = ' '; - if (c != ' ' || nxtc != ' ') - *bp1++ = c; - } while (*bp0++ && bp1 < endbp1); + while ((c = *in_str++) != '\0' && outstr < outend) { + if (c == '\n') + c = ' '; + if (was_space && c == ' ') + continue; + *outstr++ = c; + was_space = (c == ' '); + } + if ((was_space && outstr > cbuf) || outstr == outend) + --outstr; /* remove trailing space or make room for terminator */ + *outstr = '\0'; str = cbuf; } return str; From 1a1adfee3ed55f7b615f57f551ae95b964ad6211 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 23 Dec 2016 13:34:06 +0200 Subject: [PATCH 5/5] Fix valgrind complaint in wizmode terrain The code was writing characters into row[x-1] in the loop, but putting the string terminator at row[x], leaving one character between uninitialized. --- src/cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd.c b/src/cmd.c index 317405b45..a1020bdba 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -920,6 +920,7 @@ wiz_map_levltyp(VOID_ARGS) ? 'a' + terrain - 10 : 'A' + terrain - 36); } + x--; if (levl[0][y].typ != STONE || may_dig(0, y)) row[x++] = '!'; row[x] = '\0';