From 0c88c91c83d5202d44b87a09a67ae2ad81fea50c Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 8 Dec 2023 19:12:38 -0800 Subject: [PATCH] mdlib.c revisited There is a slight change in behavior here when collecting build-time option information. If MAXOPT is too small, collecting will now save MAXOPT lines and then skip anything that should come after. It used to always keep the very last line, each time replacing whatever the previous last line was, but would leak memory if that ever happened. And after yesterday's "fix" it would try to keep that very last line beyond the array bounds. --- src/mdlib.c | 62 +++++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index 59ca587ae..f66a1f0e2 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -95,6 +95,10 @@ static void build_savebones_compat_string(void); static int idxopttext, done_runtime_opt_init_once = 0; #define MAXOPT 60 /* 3.7: currently 40 lines get inserted into opttext[] */ static char *opttext[MAXOPT] = { 0 }; +#define STOREOPTTEXT(line) \ + ((void) ((idxopttext < MAXOPT) \ + ? (opttext[idxopttext++] = dupstr(line)) \ + : 0)) char optbuf[COLBUFSZ]; static struct version_info version; static const char opt_indent[] = " "; @@ -735,9 +739,7 @@ opt_out_words( if (word) *word = '\0'; if (*length_p + (int) strlen(str) > COLNO - 5) { - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); Sprintf(optbuf, "%s", opt_indent), *length_p = (int) strlen(opt_indent); } else { @@ -762,9 +764,7 @@ build_options(void) #endif #endif build_savebones_compat_string(); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) #if (NH_DEVEL_STATUS == NH_STATUS_BETA) #define STATUS_ARG " [beta]" @@ -776,13 +776,9 @@ build_options(void) #endif /* NH_DEVEL_STATUS == NH_STATUS_RELEASED */ Sprintf(optbuf, "%sNetHack version %d.%d.%d%s\n", opt_indent, VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, STATUS_ARG); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); Sprintf(optbuf, "Options compiled into this edition:"); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); optbuf[0] = '\0'; length = COLNO + 1; /* force 1st item onto new line */ for (i = 0; i < SIZE(build_opts); i++) { @@ -798,19 +794,13 @@ build_options(void) (i < SIZE(build_opts) - 1) ? "," : "."); opt_out_words(buf, &length); } - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); optbuf[0] = '\0'; winsyscnt = count_and_validate_winopts(); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); Sprintf(optbuf, "Supported windowing system%s:", (winsyscnt > 1) ? "s" : ""); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); optbuf[0] = '\0'; length = COLNO + 1; /* force 1st item onto new line */ @@ -842,19 +832,12 @@ build_options(void) #if !defined(MAKEDEFS_C) cnt = 0; - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); optbuf[0] = '\0'; soundlibcnt = count_and_validate_soundlibopts(); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; - Sprintf(optbuf, "Supported soundlib%s:", - (soundlibcnt > 1) ? "s" : ""); - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); + Sprintf(optbuf, "Supported soundlib%s:", (soundlibcnt > 1) ? "s" : ""); + STOREOPTTEXT(optbuf); optbuf[0] = '\0'; length = COLNO + 1; /* force 1st item onto new line */ @@ -892,9 +875,7 @@ build_options(void) #endif #endif /* !MAKEDEFS_C */ - opttext[idxopttext] = dupstr(optbuf); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(optbuf); optbuf[0] = '\0'; #if defined(MAKEDEFS_C) || defined(FOR_RUNTIME) @@ -920,21 +901,18 @@ build_options(void) /* add lua copyright notice; ":TAG:" substitutions are deferred to caller */ for (i = 0; lua_info[i]; ++i) { - opttext[idxopttext] = dupstr(lua_info[i]); - if (idxopttext < MAXOPT) - idxopttext++; + STOREOPTTEXT(lua_info[i]); } } #endif /* MAKEDEFS_C || FOR_RUNTIME */ /* end with a blank line */ - opttext[idxopttext] = dupstr(""); - if (idxopttext < MAXOPT) - idxopttext++; - opttext[MAXOPT - 1] = NULL; + STOREOPTTEXT(""); return; } +#undef STOREOPTTEXT + int case_insensitive_comp(const char *s1, const char *s2) {