From e83e04dbb3300e73e29870c3a4348356e2304481 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 Nov 2024 22:24:45 -0500 Subject: [PATCH] fix some memory leaks --- include/extern.h | 1 + src/options.c | 40 ++++++++++++++++++++++++++++++-------- src/save.c | 5 +++++ sys/windows/Makefile.nmake | 4 +++- sys/windows/consoletty.c | 38 ++++++++++++++++++++++++++++++++++-- win/share/safeproc.c | 27 ++++++++++++++++++++++++- 6 files changed, 103 insertions(+), 12 deletions(-) diff --git a/include/extern.h b/include/extern.h index d4abee992..81c52e11d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2255,6 +2255,7 @@ extern boolean msgtype_parse_add(char *) NONNULLARG1; extern int msgtype_type(const char *, boolean) NONNULLARG1; extern void hide_unhide_msgtypes(boolean, int); extern void msgtype_free(void); +extern void options_free_window_colors(void); /* ### pager.c ### */ diff --git a/src/options.c b/src/options.c index 769f0d840..e9da50d52 100644 --- a/src/options.c +++ b/src/options.c @@ -3451,6 +3451,9 @@ optfn_roguesymset( } if (req == do_set) { if (op != empty_optstr) { + if (gs.symset[ROGUESET].name) + free((genericptr_t) gs.symset[ROGUESET].name), + gs.symset[ROGUESET].name = 0; gs.symset[ROGUESET].name = dupstr(op); if (!read_sym_file(ROGUESET)) { clear_symsetentry(ROGUESET, TRUE); @@ -4066,6 +4069,9 @@ optfn_symset( } if (req == do_set) { if (op != empty_optstr) { + if (gs.symset[PRIMARYSET].name) + free((genericptr_t) gs.symset[PRIMARYSET].name), + gs.symset[PRIMARYSET].name = 0; gs.symset[PRIMARYSET].name = dupstr(op); if (!read_sym_file(PRIMARYSET)) { clear_symsetentry(PRIMARYSET, TRUE); @@ -9821,6 +9827,16 @@ wc_set_font_name(int opttype, char *fontname) return; } +static char **fgp[] = { &iflags.wcolors[wcolor_menu].fg, + &iflags.wcolors[wcolor_message].fg, + &iflags.wcolors[wcolor_status].fg, + &iflags.wcolors[wcolor_text].fg }; +static char **bgp[] = { &iflags.wcolors[wcolor_menu].bg, + &iflags.wcolors[wcolor_message].bg, + &iflags.wcolors[wcolor_status].bg, + &iflags.wcolors[wcolor_text].bg }; +int options_set_window_colors_flag = 0; + staticfn int wc_set_window_colors(char *op) { @@ -9828,14 +9844,7 @@ wc_set_window_colors(char *op) * menu white/black message green/yellow status white/blue text * white/black */ - static char **fgp[] = { &iflags.wcolors[wcolor_menu].fg, - &iflags.wcolors[wcolor_message].fg, - &iflags.wcolors[wcolor_status].fg, - &iflags.wcolors[wcolor_text].fg }; - static char **bgp[] = { &iflags.wcolors[wcolor_menu].bg, - &iflags.wcolors[wcolor_message].bg, - &iflags.wcolors[wcolor_status].bg, - &iflags.wcolors[wcolor_text].bg }; + int j; int32 clr; char buf[BUFSZ]; @@ -9917,9 +9926,24 @@ wc_set_window_colors(char *op) wn); } } + options_set_window_colors_flag = 1; return 1; } +void +options_free_window_colors(void) +{ + int j; + + for (j = 0; j < WC_COUNT; ++j) { + if (*fgp[j]) + free((genericptr_t) *fgp[j]), *fgp[j] = 0; + if (*bgp[j]) + free((genericptr_t) *bgp[j]), *bgp[j] = 0; + } + options_set_window_colors_flag = 0; +} + /* set up for wizard mode if player or save file has requested it; called from port-specific startup code to handle `nethack -D' or OPTIONS=playmode:debug, or from dorecover()'s restgamestate() if diff --git a/src/save.c b/src/save.c index 509e3c437..b98194da7 100644 --- a/src/save.c +++ b/src/save.c @@ -1177,6 +1177,8 @@ free_dungeons(void) return; } +extern int options_set_window_colors_flag; /* options.c */ + /* free a lot of allocated memory which is ordinarily freed during save */ void freedynamicdata(void) @@ -1272,6 +1274,9 @@ freedynamicdata(void) if (VIA_WINDOWPORT()) status_finish(); + if (options_set_window_colors_flag) + options_free_window_colors(); + /* last, because it frees data that might be used by panic() to provide feedback to the user; conceivably other freeing might trigger panic */ sysopt_release(); /* SYSCF strings */ diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index b763e7858..2104b0afc 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -1972,12 +1972,14 @@ $(SRC)\tiles.bmp: $(U)tile2bmp.exe $(TILEFILES) @echo Creating 16x16 binary tile files (this may take some time) @$(U)tile2bmp $@ -$(U)tile2bmp.exe: $(OUTL)tile2bmp.o $(TEXT_IO) +$(U)tile2bmp.exe: $(OUTL)tile2bmp.o $(TEXT_IO) $(OUTL)alloc.o $(OUTL)panic.o @echo Linking $(@:\=/) @$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" $(OUTLHACKLIB) -out:$@ @<<$(@B).lnk $(OUTL)tile2bmp.o $(TEXT_IO:^ =^ ) + $(OUTL)alloc.o + $(OUTL)panic.o << $(U)til2bm32.exe: $(OUTL)til2bm32.o $(TEXT_IO32) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index d88cb0881..be382fdd2 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -145,6 +145,9 @@ extern void (*ibmgraphics_mode_callback)(void); /* symbols.c */ extern void (*utf8graphics_mode_callback)(void); /* symbols.c */ #endif /* VIRTUAL_TERMINAL_SEQUENCES */ +static void init_custom_colors(void); +static void free_custom_colors(void); + /* Win32 Screen buffer,coordinate,console I/O information */ COORD ntcoord; INPUT_RECORD ir; @@ -317,8 +320,8 @@ WHITE 255,255,255 242,242,242 #ifdef VIRTUAL_TERMINAL_SEQUENCES long customcolors[CLR_MAX]; -const char *esc_seq_colors[CLR_MAX]; -const char *esc_seq_bkcolors[CLR_MAX]; +const char *esc_seq_colors[CLR_MAX] = { 0 }; +const char *esc_seq_bkcolors[CLR_MAX] = { 0 }; struct rgbvalues { int idx; @@ -551,6 +554,32 @@ init_custom_colors(void) esc_seq_bkcolors[CLR_BRIGHT_CYAN] = dupstr(bkcolorbuf); } +static void +free_custom_colors(void) +{ +#define CLR_FREE(c) \ + if (esc_seq_bkcolors[(c)] != 0) \ + free((genericptr_t) esc_seq_bkcolors[(c)]), esc_seq_bkcolors[(c)] = 0 + + CLR_FREE(CLR_BLACK); + CLR_FREE(CLR_RED); + CLR_FREE(CLR_GREEN); + CLR_FREE(CLR_YELLOW); + CLR_FREE(CLR_BLUE); + CLR_FREE(CLR_MAGENTA); + CLR_FREE(CLR_CYAN); + CLR_FREE(CLR_WHITE); + CLR_FREE(CLR_BROWN); + CLR_FREE(CLR_GRAY); + CLR_FREE(NO_COLOR); + CLR_FREE(CLR_ORANGE); + CLR_FREE(CLR_BRIGHT_GREEN); + CLR_FREE(CLR_BRIGHT_BLUE); + CLR_FREE(CLR_BRIGHT_MAGENTA); + CLR_FREE(CLR_BRIGHT_CYAN); +#undef CLR_FREE +} + void emit_start_bold(void); void emit_stop_bold(void); void emit_start_dim(void); @@ -1099,8 +1128,13 @@ consoletty_open(int mode) void consoletty_exit(void) { + /* frees some status tracking data */ + genl_status_finish(); /* go back to using the safe routines */ safe_routines(); + free_custom_colors(); + free((genericptr_t) console.localestr); + free((genericptr_t) console.orig_localestr); } int diff --git a/win/share/safeproc.c b/win/share/safeproc.c index 32dec1a5b..2862117ff 100644 --- a/win/share/safeproc.c +++ b/win/share/safeproc.c @@ -66,7 +66,32 @@ */ struct window_procs safe_procs = { - WPID(safestartup), 0L, 0L, + WPID(safestartup), + (0 +#ifdef TTY_PERM_INVENT + | WC_PERM_INVENT +#endif +#ifdef MSDOS + | WC_TILED_MAP | WC_ASCII_MAP +#endif +#if defined(WIN32CON) + | WC_MOUSE_SUPPORT +#endif + | WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN), + (0 +#if defined(SELECTSAVED) + | WC2_SELECTSAVED +#endif +#if defined(STATUS_HILITES) + | WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS + | WC2_RESET_STATUS +#endif + | WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_URGENT_MESG | WC2_STATUSLINES + | WC2_U_UTF8STR | WC2_PETATTR +#if !defined(NO_TERMS) || defined(WIN32CON) + | WC2_EXTRACOLORS +#endif + ), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ safe_init_nhwindows, safe_player_selection, safe_askname, safe_get_nh_event,