From 9a9f76bf5c908657d6635d8473863f724aa9f12d Mon Sep 17 00:00:00 2001 From: keni Date: Sat, 29 Dec 2018 19:19:30 -0500 Subject: [PATCH 1/5] fix typos in header line so expansion works --- doc/fixes36.2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 7e1b29810..52cf55f1b 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: $:$NHDT-Revision: $ $NHDT-Date: $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.217 $ $NHDT-Date: 1546129154 2018/12/30 00:19:14 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, From d418008b31109b70c812dcd5a810d5bd646fd656 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 29 Dec 2018 18:38:30 -0800 Subject: [PATCH 2/5] curses splash/copyright screen, role prompt Back out '#include "date.h"' so that cursinit.c won't be recompiled every time any other file(s) need to be compiled. It doesn't need patchlevel.h either. There is already a straightforward way to fetch the copyright banner lines from version.c. The splash screen (ascii art spelling "NetHack" preceding the normal copyright lines) was invisible when showing white text on white-ish background. Make it honor !guicolor. "Shall I pick a character's role, race, gender and alignment for you? [ynaq] (y) " was too wide to accept the answer on the same line on an 80-column display so "(y) " was placed on the second line. That's constructed in the core; change the construction to omit " a" when using "character" rather than a role name. (tty shortens it by omitting the default " (y)"; with " a" gone, it could revert to normal prompt.) Also a bit of lint cleanup and some reformatting of cursinit.c.... --- src/role.c | 9 ++- src/version.c | 5 +- sys/unix/Makefile.src | 4 +- win/curses/cursinit.c | 159 ++++++++++++++++++++---------------------- win/curses/cursinvt.c | 4 +- 5 files changed, 86 insertions(+), 95 deletions(-) diff --git a/src/role.c b/src/role.c index 69adcab7b..860f7644e 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 role.c $NHDT-Date: 1463561393 2016/05/18 08:49:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 3.6 role.c $NHDT-Date: 1546137492 2018/12/30 02:38:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.55 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1631,13 +1631,16 @@ int buflen, rolenum, racenum, gendnum, alignnum; Strcpy(tmpbuf, "Shall I pick "); if (racenum != ROLE_NONE || validrole(rolenum)) Strcat(tmpbuf, "your "); - else { + else Strcat(tmpbuf, "a "); - } /* */ (void) root_plselection_prompt(eos(tmpbuf), buflen - strlen(tmpbuf), rolenum, racenum, gendnum, alignnum); + /* "Shall I pick a character's role, race, gender, and alignment for you?" + plus " [ynaq] (y)" is a little too long for a conventional 80 columns; + also, "pick a character's " sounds a bit stilted */ + strsubst(tmpbuf, "pick a character", "pick character"); Sprintf(buf, "%s", s_suffix(tmpbuf)); /* don't bother splitting caveman/cavewoman or priest/priestess in order to apply possessive suffix to both halves, but do diff --git a/src/version.c b/src/version.c index 9b3763841..94f1f3024 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 version.c $NHDT-Date: 1524693365 2018/04/25 21:56:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */ +/* NetHack 3.6 version.c $NHDT-Date: 1546137502 2018/12/30 02:38:22 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.51 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -68,7 +68,8 @@ char *buf; #if defined(NETHACK_GIT_BRANCH) #if defined(BETA) if (NetHack_git_branch) - Sprintf(eos(buf), "%sbranch:%s", c++ ? "," : "", NetHack_git_branch); + Sprintf(eos(buf), "%sbranch:%s", + c++ ? "," : "", NetHack_git_branch); #endif #endif Sprintf(eos(buf), ")"); diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 40892e1ed..a889a9af1 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1543447374 2018/11/28 23:22:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.60 $ +# NetHack 3.6 Makefile.src $NHDT-Date: 1546137503 2018/12/30 02:38:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.66 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -790,7 +790,7 @@ cursstat.o: ../win/curses/cursstat.c $(HACK_H) ../include/wincurs.h \ ../win/curses/cursstat.h $(CC) $(CFLAGS) -c ../win/curses/cursstat.c cursinit.o: ../win/curses/cursinit.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursinit.h ../include/patchlevel.h ../include/date.h + ../win/curses/cursinit.h $(CC) $(CFLAGS) -c ../win/curses/cursinit.c cursmesg.o: ../win/curses/cursmesg.c $(HACK_H) ../include/wincurs.h \ ../win/curses/cursmesg.h diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 879b486a3..6c5c42b83 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -7,8 +7,7 @@ #include "hack.h" #include "wincurs.h" #include "cursinit.h" -#include "patchlevel.h" -#include "date.h" +/*#include "patchlevel.h"*/ #include @@ -60,11 +59,13 @@ nhrgb orig_hiwhite; "|_| \\_| \\___| \\__||_| |_| \\__,_| \\___||_|\\_\\" -/* win* is size and placement of window to change, x/y/w/h is baseline which can - decrease depending on alignment of win* in orientation. - Negative minh/minw: as much as possible, but at least as much as specified. */ +/* win* is size and placement of window to change, x/y/w/h is baseline + which can decrease depending on alignment of win* in orientation. + Negative minh/minw: as much as possible, but at least as much as + specified. */ static void -set_window_position(int *winx, int *winy, int *winw, int *winh, int orientation, +set_window_position(int *winx, int *winy, int *winw, int *winh, + int orientation, int *x, int *y, int *w, int *h, int border_space, int minh, int minw) { @@ -107,7 +108,6 @@ set_window_position(int *winx, int *winy, int *winw, int *winh, int orientation, } /* Create the "main" nonvolitile windows used by nethack */ - void curses_create_main_windows() { @@ -178,10 +178,11 @@ curses_create_main_windows() } } - /* Figure out window positions and placements. Status and message area can be aligned - based on configuration. The priority alignment-wise is: status > msgarea > game. - Define everything as taking as much space as possible and shrink/move based on - alignment positions. */ + /* Figure out window positions and placements. Status and message area + can be aligned based on configuration. The priority alignment-wise + is: status > msgarea > game. + Define everything as taking as much space as possible and shrink/move + based on alignment positions. */ { int message_x = 0; int message_y = 0; @@ -204,6 +205,7 @@ curses_create_main_windows() boolean status_vertical = FALSE; boolean msg_vertical = FALSE; + if (status_orientation == ALIGN_LEFT || status_orientation == ALIGN_RIGHT) status_vertical = TRUE; @@ -217,8 +219,10 @@ curses_create_main_windows() /* Vertical windows have priority. Otherwise, priotity is: status > inv > msg */ if (status_vertical) - set_window_position(&status_x, &status_y, &status_width, &status_height, - status_orientation, &map_x, &map_y, &map_width, &map_height, + set_window_position(&status_x, &status_y, + &status_width, &status_height, + status_orientation, + &map_x, &map_y, &map_width, &map_height, border_space, statusheight, 26); if (iflags.perm_invent) { @@ -228,24 +232,31 @@ curses_create_main_windows() width = 25; set_window_position(&inv_x, &inv_y, &inv_width, &inv_height, - ALIGN_RIGHT, &map_x, &map_y, &map_width, &map_height, + ALIGN_RIGHT, &map_x, &map_y, + &map_width, &map_height, border_space, -1, width); } if (msg_vertical) - set_window_position(&message_x, &message_y, &message_width, &message_height, - message_orientation, &map_x, &map_y, &map_width, &map_height, + set_window_position(&message_x, &message_y, + &message_width, &message_height, + message_orientation, + &map_x, &map_y, &map_width, &map_height, border_space, -1, -25); /* Now draw horizontal windows */ if (!status_vertical) - set_window_position(&status_x, &status_y, &status_width, &status_height, - status_orientation, &map_x, &map_y, &map_width, &map_height, + set_window_position(&status_x, &status_y, + &status_width, &status_height, + status_orientation, + &map_x, &map_y, &map_width, &map_height, border_space, statusheight, 26); if (!msg_vertical) - set_window_position(&message_x, &message_y, &message_width, &message_height, - message_orientation, &map_x, &map_y, &map_width, &map_height, + set_window_position(&message_x, &message_y, + &message_width, &message_height, + message_orientation, + &map_x, &map_y, &map_width, &map_height, border_space, -1, -25); if (map_width > COLNO) @@ -273,7 +284,8 @@ curses_create_main_windows() curses_add_nhwin(INV_WIN, inv_height, inv_width, inv_y, inv_x, ALIGN_RIGHT, borders); - curses_add_nhwin(MAP_WIN, map_height, map_width, map_y, map_x, 0, borders); + curses_add_nhwin(MAP_WIN, map_height, map_width, + map_y, map_x, 0, borders); refresh(); @@ -290,9 +302,7 @@ curses_create_main_windows() } } - /* Initialize curses colors to colors used by NetHack */ - void curses_init_nhcolors() { @@ -312,7 +322,7 @@ curses_init_nhcolors() int i; boolean hicolor = FALSE; - int clr_remap[16] = { + static const int clr_remap[16] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, -1, COLOR_WHITE, @@ -329,7 +339,8 @@ curses_init_nhcolors() if (COLORS >= 16) hicolor = TRUE; - /* Work around the crazy definitions above for more background colors... */ + /* Work around the crazy definitions above for more background + colors... */ for (i = 0; i < (COLORS >= 16 ? 16 : 8); i++) { init_pair((hicolor ? 49 : 9) + i, clr_remap[i], COLOR_GREEN); init_pair((hicolor ? 65 : 33) + i, clr_remap[i], COLOR_YELLOW); @@ -403,10 +414,8 @@ curses_init_nhcolors() #endif } - /* Allow player to pick character's role, race, gender, and alignment. -Borrowed from the Gnome window port. */ - + Borrowed from the Gnome window port. */ void curses_choose_character() { @@ -427,7 +436,6 @@ curses_choose_character() /* This part is irritating: we have to strip the choices off of the string and put them in a separate string in order to use curses_character_input_dialog for this prompt. */ - while (cur_character != '[') { cur_character = prompt[count]; count++; @@ -455,7 +463,6 @@ curses_choose_character() } /* Add capital letters as choices that aren't displayed */ - for (count = 0; tmpchoice[count]; count++) { tmpchoice[count] = toupper(tmpchoice[count]); } @@ -493,7 +500,8 @@ curses_choose_character() pickmap = (int *) alloc(sizeof (int) * (n + 1)); for (;;) { for (n = 0, i = 0; roles[i].name.m; i++) { - if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { + if (ok_role(i, flags.initrace, + flags.initgend, flags.initalign)) { if (flags.initgend >= 0 && flags.female && roles[i].name.f) choices[n] = roles[i].name.f; else @@ -514,8 +522,7 @@ curses_choose_character() } choices[n] = (const char *) 0; if (n > 1) - sel = - curses_character_dialog(choices, + sel = curses_character_dialog(choices, "Choose one of the following roles:"); else sel = 0; @@ -554,7 +561,8 @@ curses_choose_character() /* Count the number of valid races */ n = 0; /* number valid */ for (i = 0; races[i].noun; i++) { - if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) + if (ok_race(flags.initrole, i, + flags.initgend, flags.initalign)) n++; } if (n == 0) { @@ -567,7 +575,8 @@ curses_choose_character() choices = (const char **) alloc(sizeof (char *) * (n + 1)); pickmap = (int *) alloc(sizeof (int) * (n + 1)); for (n = 0, i = 0; races[i].noun; i++) { - if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { + if (ok_race(flags.initrole, i, + flags.initgend, flags.initalign)) { choices[n] = races[i].noun; pickmap[n++] = i; } @@ -575,9 +584,8 @@ curses_choose_character() choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) - sel = - curses_character_dialog(choices, - "Choose one of the following races:"); + sel = curses_character_dialog(choices, + "Choose one of the following races:"); else sel = 0; if (sel >= 0) @@ -613,7 +621,8 @@ curses_choose_character() /* Count the number of valid genders */ n = 0; /* number valid */ for (i = 0; i < ROLE_GENDERS; i++) { - if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) + if (ok_gend(flags.initrole, flags.initrace, + i, flags.initalign)) n++; } if (n == 0) { @@ -626,7 +635,8 @@ curses_choose_character() choices = (const char **) alloc(sizeof (char *) * (n + 1)); pickmap = (int *) alloc(sizeof (int) * (n + 1)); for (n = 0, i = 0; i < ROLE_GENDERS; i++) { - if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { + if (ok_gend(flags.initrole, flags.initrace, + i, flags.initalign)) { choices[n] = genders[i].adj; pickmap[n++] = i; } @@ -634,9 +644,8 @@ curses_choose_character() choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) - sel = - curses_character_dialog(choices, - "Choose one of the following genders:"); + sel = curses_character_dialog(choices, + "Choose one of the following genders:"); else sel = 0; if (sel >= 0) @@ -671,7 +680,8 @@ curses_choose_character() /* Count the number of valid alignments */ n = 0; /* number valid */ for (i = 0; i < ROLE_ALIGNS; i++) { - if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) + if (ok_align(flags.initrole, flags.initrace, + flags.initgend, i)) n++; } if (n == 0) { @@ -683,7 +693,8 @@ curses_choose_character() choices = (const char **) alloc(sizeof (char *) * (n + 1)); pickmap = (int *) alloc(sizeof (int) * (n + 1)); for (n = 0, i = 0; i < ROLE_ALIGNS; i++) { - if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { + if (ok_align(flags.initrole, flags.initrace, + flags.initgend, i)) { choices[n] = aligns[i].adj; pickmap[n++] = i; } @@ -691,9 +702,8 @@ curses_choose_character() choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) - sel = - curses_character_dialog(choices, - "Choose one of the following alignments:"); + sel = curses_character_dialog(choices, + "Choose one of the following alignments:"); else sel = 0; if (sel >= 0) @@ -716,9 +726,7 @@ curses_choose_character() } } - /* Prompt user for character race, role, alignment, or gender */ - int curses_character_dialog(const char **choices, const char *prompt) { @@ -771,14 +779,12 @@ curses_character_dialog(const char **choices, const char *prompt) return ret; } - /* Initialize and display options appropriately */ - void curses_init_options() { - set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | - WC_HILITE_PET | WC_POPUP_DIALOG, SET_IN_GAME); + set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR + | WC_HILITE_PET | WC_POPUP_DIALOG, SET_IN_GAME); set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_GAME); @@ -792,9 +798,10 @@ curses_init_options() /* Make sure that DECgraphics is not set to true via the config file, as this will cause display issues. We can't disable it in options.c in case the game is compiled with both tty and curses. */ - if (!symset[PRIMARY].name || !strcmpi(symset[PRIMARY].name, "DECgraphics")) { - load_symset("curses",PRIMARY); - load_symset("default",ROGUESET); + if (!symset[PRIMARY].name + || !strcmpi(symset[PRIMARY].name, "DECgraphics")) { + load_symset("curses", PRIMARY); + load_symset("default", ROGUESET); } #ifdef PDCURSES /* PDCurses for SDL, win32 and OS/2 has the ability to set the @@ -830,7 +837,7 @@ curses_init_options() if (!iflags.wc2_petattr) { iflags.wc2_petattr = A_REVERSE; - } else { /* Pet attribute specified, so hilite_pet should be true */ + } else { /* Pet attribute specified, so hilite_pet should be true */ iflags.hilite_pet = TRUE; } @@ -842,14 +849,11 @@ curses_init_options() #endif } - /* Display an ASCII splash screen if the splash_screen option is set */ - void curses_display_splash_window() { - int x_start; - int y_start; + int i, x_start, y_start; curses_get_window_xy(MAP_WIN, &x_start, &y_start); @@ -857,8 +861,9 @@ curses_display_splash_window() iflags.wc_splash_screen = FALSE; /* No room for s.s. */ } - curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, ON); if (iflags.wc_splash_screen) { + if (iflags.wc2_guicolor) + curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, ON); mvaddstr(y_start, x_start, NETHACK_SPLASH_A); mvaddstr(y_start + 1, x_start, NETHACK_SPLASH_B); mvaddstr(y_start + 2, x_start, NETHACK_SPLASH_C); @@ -867,34 +872,18 @@ curses_display_splash_window() mvaddstr(y_start + 5, x_start, NETHACK_SPLASH_F); y_start += 7; } + if (iflags.wc2_guicolor) + curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, OFF); - curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, OFF); + for (i = 1; i <= 4; ++i) { + mvaddstr(y_start, x_start, copyright_banner_line(i)); + y_start++; + } -#ifdef COPYRIGHT_BANNER_A - mvaddstr(y_start, x_start, COPYRIGHT_BANNER_A); - y_start++; -#endif - -#ifdef COPYRIGHT_BANNER_B - mvaddstr(y_start, x_start, COPYRIGHT_BANNER_B); - y_start++; -#endif - -#ifdef COPYRIGHT_BANNER_C - mvaddstr(y_start, x_start, COPYRIGHT_BANNER_C); - y_start++; -#endif - -#ifdef COPYRIGHT_BANNER_D /* Just in case */ - mvaddstr(y_start, x_start, COPYRIGHT_BANNER_D); - y_start++; -#endif refresh(); } - /* Resore colors and cursor state before exiting */ - void curses_cleanup() { diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 6e66d539d..b96037e01 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -16,9 +16,7 @@ curses_update_inv(void) { WINDOW *win = curses_get_nhwin(INV_WIN); boolean border; - int x = 0; - int y = 0; - attr_t attr = A_UNDERLINE; + int x = 0, y = 0; /* Check if the inventory window is enabled in first place */ if (!win) { From 39b6f7f4628a073f0ea0cc34c12581fab7051a0a Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 29 Dec 2018 20:39:11 -0800 Subject: [PATCH 3/5] alphabet sour warning A recently added impossible to check for an(Null) and an("") was triggered by the fuzzer: Alphabet soup: 'an("")'. I reproduced it a couple of times and tracked it do_screen_description(for '/' command) matching the symbol from mapglyph to monster class #0, a placeholder with symbol value '\0'. So mapglyph() returned a symbol of '\0', but not necessary from showsyms[0 + SYM_OFF_M]. The pager lookup code's monster loop shouldn't have been attempting to match against class #0, and since this fix I haven't been able to reproduce the situation again. But I also didn't trigger it with a bunch of temporary checks in mapglyph() so don't know what is really going on under the hood. --- doc/fixes36.2 | 6 +++++- src/pager.c | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 52cf55f1b..1f858d9a9 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.217 $ $NHDT-Date: 1546129154 2018/12/30 00:19:14 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.218 $ $NHDT-Date: 1546144745 2018/12/30 04:39:05 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -357,6 +357,10 @@ when built with STATUS_HILITES enabled (the default), gold on status line was missing '$' prefix for symset:Blank wizard mode ^G, creating a monster of class 'I' yielded impossible "mkclass found no class 35 monsters" +in some unknown circumstance, examining something on the map could match bogus + monster class #0 and trigger impossible "Alphabet soup: 'an("")'." + (fix avoids the warning but underlying cause is a mystery; noticed + with the fuzzer, which swaps symbol sets in and out at random) tty: turn off an optimization that is the suspected cause of Windows reported partial status lines following level changes tty: ensure that current status fields are always copied to prior status diff --git a/src/pager.c b/src/pager.c index 2ae5d8074..5b7f43c48 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pager.c $NHDT-Date: 1545774524 2018/12/25 21:48:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.145 $ */ +/* NetHack 3.6 pager.c $NHDT-Date: 1546144745 2018/12/30 04:39:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.146 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -861,9 +861,9 @@ struct permonst **for_supplement; /* Check for monsters */ if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) { - for (i = 0; i < MAXMCLASSES; i++) { + for (i = 1; i < MAXMCLASSES; i++) { if (sym == (looked ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym) - && def_monsyms[i].explain) { + && def_monsyms[i].explain && *def_monsyms[i].explain) { need_to_look = TRUE; if (!found) { Sprintf(out_str, "%s%s", @@ -1235,7 +1235,7 @@ coord *click_cc; } found = do_screen_description(cc, (from_screen || clicklook), sym, - out_str, &firstmatch, &supplemental_pm); + out_str, &firstmatch, &supplemental_pm); /* Finally, print out our explanation. */ if (found) { From adf64764f4859987b866a3bf822ce8b49653f39f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 29 Dec 2018 20:41:16 -0800 Subject: [PATCH 4/5] minor memory leak I ran the fuzzer with MONITOR_HEAP enabled and heaputil found a dozen or so un-free'd allocations, all made by the same dupstr() call in special_handling() for "symset" and "roguesymset". (Reproducible with a few tens of thousands of fuzzer moves, although you have to take over from the fuzzer and make a clean exit rather than just interrupt it or there'll be lots of other un-free'd memory.) I haven't actually figured out how/why it was leaking, but reorganizing the code has made the leak go away (according to a couple of even longer fuzzer runs) so I'm settling for that. --- src/files.c | 29 +++++--------- src/options.c | 106 ++++++++++++++++++-------------------------------- 2 files changed, 46 insertions(+), 89 deletions(-) diff --git a/src/files.c b/src/files.c index a73349c3e..00d1fe972 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1545702598 2018/12/25 01:49:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.248 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1546144856 2018/12/30 04:40:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.249 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3264,37 +3264,26 @@ int which_set; switch (symp->idx) { case 0: - tmpsp = - (struct symsetentry *) alloc(sizeof (struct symsetentry)); - tmpsp->next = (struct symsetentry *) 0; - if (!symset_list) { - symset_list = tmpsp; - symset_count = 0; - } else { - symset_count++; - tmpsp->next = symset_list; - symset_list = tmpsp; - } - tmpsp->idx = symset_count; + tmpsp = (struct symsetentry *) alloc(sizeof *tmpsp); + tmpsp->next = symset_list; + symset_list = tmpsp; + tmpsp->idx = symset_count++; tmpsp->name = dupstr(bufp); tmpsp->desc = (char *) 0; - tmpsp->nocolor = 0; + tmpsp->handling = H_UNK; /* initialize restriction bits */ + tmpsp->nocolor = 0; tmpsp->primary = 0; tmpsp->rogue = 0; break; case 2: /* handler type identified */ tmpsp = symset_list; /* most recent symset */ - tmpsp->handling = H_UNK; - i = 0; - while (known_handling[i]) { + for (i = 0; known_handling[i]; ++i) if (!strcmpi(known_handling[i], bufp)) { tmpsp->handling = i; - break; /* while loop */ + break; /* for loop */ } - i++; - } break; case 3: /* description:something */ tmpsp = symset_list; /* most recent symset */ diff --git a/src/options.c b/src/options.c index 17965cb05..564abf833 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1544773907 2018/12/14 07:51:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.347 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1546144857 2018/12/30 04:40:57 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.349 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5201,8 +5201,7 @@ boolean setinitial, setfromfile; } else if (!strcmp("symset", optname) || !strcmp("roguesymset", optname)) { menu_item *symset_pick = (menu_item *) 0; - boolean primaryflag = (*optname == 's'), - rogueflag = (*optname == 'r'), + boolean rogueflag = (*optname == 'r'), ready_to_switch = FALSE, nothing_to_do = FALSE; char *symset_name, fmtstr[20]; @@ -5210,37 +5209,33 @@ boolean setinitial, setfromfile; int res, which_set, setcount = 0, chosen = -2; which_set = rogueflag ? ROGUESET : PRIMARY; - + symset_list = (struct symsetentry *) 0; /* clear symset[].name as a flag to read_sym_file() to build list */ symset_name = symset[which_set].name; symset[which_set].name = (char *) 0; - symset_list = (struct symsetentry *) 0; res = read_sym_file(which_set); - if (res && symset_list) { - char symsetchoice[BUFSZ]; - int let = 'a', biggest = 0, thissize = 0; - sl = symset_list; - while (sl) { + /* put symset name back */ + symset[which_set].name = symset_name; + + if (res && symset_list) { + int thissize, biggest = 0; + + for (sl = symset_list; sl; sl = sl->next) { /* check restrictions */ - if ((!rogueflag && sl->rogue) - || (!primaryflag && sl->primary)) { - sl = sl->next; + if (rogueflag ? sl->primary : sl->rogue) continue; - } + setcount++; /* find biggest name */ - if (sl->name) - thissize = strlen(sl->name); + thissize = sl->name ? (int) strlen(sl->name) : 0; if (thissize > biggest) biggest = thissize; - sl = sl->next; } if (!setcount) { - pline("There are no appropriate %ssymbol sets available.", - (rogueflag) ? "rogue level " - : (primaryflag) ? "primary " : ""); + pline("There are no appropriate %s symbol sets available.", + rogueflag ? "rogue level" : "primary"); return TRUE; } @@ -5249,29 +5244,20 @@ boolean setinitial, setfromfile; start_menu(tmpwin); any = zeroany; any.a_int = 1; - add_menu(tmpwin, NO_GLYPH, &any, let++, 0, ATR_NONE, + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "Default Symbols", MENU_UNSELECTED); - sl = symset_list; - while (sl) { + for (sl = symset_list; sl; sl = sl->next) { /* check restrictions */ - if ((!rogueflag && sl->rogue) - || (!primaryflag && sl->primary)) { - sl = sl->next; + if (rogueflag ? sl->primary : sl->rogue) continue; - } + if (sl->name) { any.a_int = sl->idx + 2; - Sprintf(symsetchoice, fmtstr, sl->name, - sl->desc ? sl->desc : ""); - add_menu(tmpwin, NO_GLYPH, &any, let, 0, ATR_NONE, - symsetchoice, MENU_UNSELECTED); - if (let == 'z') - let = 'A'; - else - let++; + Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : ""); + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + buf, MENU_UNSELECTED); } - sl = sl->next; } Sprintf(buf, "Select %ssymbol set:", rogueflag ? "rogue level " : ""); @@ -5284,30 +5270,20 @@ boolean setinitial, setfromfile; if (chosen > -1) { /* chose an actual symset name from file */ - sl = symset_list; - while (sl) { - if (sl->idx == chosen) { - if (symset_name) { - free((genericptr_t) symset_name); - symset_name = (char *) 0; - } - /* free the now stale attributes */ - clear_symsetentry(which_set, TRUE); - - /* transfer only the name of the symbol set */ - symset[which_set].name = dupstr(sl->name); - ready_to_switch = TRUE; + for (sl = symset_list; sl; sl = sl->next) + if (sl->idx == chosen) break; - } - sl = sl->next; + if (sl) { + /* free the now stale attributes */ + clear_symsetentry(which_set, TRUE); + + /* transfer only the name of the symbol set */ + symset[which_set].name = dupstr(sl->name); + ready_to_switch = TRUE; } } else if (chosen == -1) { /* explicit selection of defaults */ /* free the now stale symset attributes */ - if (symset_name) { - free((genericptr_t) symset_name); - symset_name = (char *) 0; - } clear_symsetentry(which_set, TRUE); } else nothing_to_do = TRUE; @@ -5322,26 +5298,18 @@ boolean setinitial, setfromfile; } /* clean up */ - while (symset_list) { - sl = symset_list; - if (sl->name) - free((genericptr_t) sl->name); - sl->name = (char *) 0; - - if (sl->desc) - free((genericptr_t) sl->desc); - sl->desc = (char *) 0; - + while ((sl = symset_list) != 0) { symset_list = sl->next; + if (sl->name) + free((genericptr_t) sl->name), sl->name = (char *) 0; + if (sl->desc) + free((genericptr_t) sl->desc), sl->desc = (char *) 0; free((genericptr_t) sl); } if (nothing_to_do) return TRUE; - if (!symset[which_set].name && symset_name) - symset[which_set].name = symset_name; /* not dupstr() here */ - /* Set default symbols and clear the handling value */ if (rogueflag) init_r_symbols(); @@ -5349,6 +5317,7 @@ boolean setinitial, setfromfile; init_l_symbols(); if (symset[which_set].name) { + /* non-default symbols */ if (read_sym_file(which_set)) { ready_to_switch = TRUE; } else { @@ -5367,7 +5336,6 @@ boolean setinitial, setfromfile; assign_graphics(PRIMARY); preference_update("symset"); need_redraw = TRUE; - return TRUE; } else { /* didn't match any of the special options */ From 83e8033f72b610b154d6b8a2eacc51baf2f3676c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 30 Dec 2018 07:58:39 -0500 Subject: [PATCH 5/5] remove curses date.h dependency in Windows Makefiles --- sys/winnt/Makefile.gcc | 4 ++-- sys/winnt/Makefile.msc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index e2ba4e86c..4450e1f75 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.gcc $NHDT-Date: 1546018468 2018/12/28 17:34:28 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.69 $ +# NetHack 3.6 Makefile.gcc $NHDT-Date: 1546174698 2018/12/30 12:58:18 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.71 $ # Copyright (c) 2010 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -1454,7 +1454,7 @@ $(O)panic.o: $(U)panic.c $(CONFIG_H) ifeq "$(ADD_CURSES)" "Y" # curses window port dependencies $(O)cursdial.o: $(WCURSES)/cursdial.c $(WCURSES)/cursdial.h $(INCL)/wincurs.h -$(O)cursinit.o: $(WCURSES)/cursinit.c $(WCURSES)/cursinit.h $(INCL)/wincurs.h $(INCL)/date.h +$(O)cursinit.o: $(WCURSES)/cursinit.c $(WCURSES)/cursinit.h $(INCL)/wincurs.h $(O)cursinvt.o: $(WCURSES)/cursinvt.c $(WCURSES)/cursinvt.h $(INCL)/wincurs.h $(O)cursmain.o: $(WCURSES)/cursmain.c $(INCL)/wincurs.h $(O)cursmesg.o: $(WCURSES)/cursmesg.c $(WCURSES)/cursmesg.h $(INCL)/wincurs.h diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index ca2ea5156..6dcd10d4d 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1546018476 2018/12/28 17:34:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.145 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1546174708 2018/12/30 12:58:28 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.147 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -1489,7 +1489,7 @@ $(O)panic.o: $(U)panic.c $(CONFIG_H) # curses window port dependencies # $(O)cursdial.o: $(WCURSES)\cursdial.c $(WCURSES)\cursdial.h $(INCL)\wincurs.h -$(O)cursinit.o: $(WCURSES)\cursinit.c $(WCURSES)\cursinit.h $(INCL)\wincurs.h $(INCL)\date.h +$(O)cursinit.o: $(WCURSES)\cursinit.c $(WCURSES)\cursinit.h $(INCL)\wincurs.h $(O)cursinvt.o: $(WCURSES)\cursinvt.c $(WCURSES)\cursinvt.h $(INCL)\wincurs.h $(O)cursmain.o: $(WCURSES)\cursmain.c $(INCL)\wincurs.h $(O)cursmesg.o: $(WCURSES)\cursmesg.c $(WCURSES)\cursmesg.h $(INCL)\wincurs.h