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.
This commit is contained in:
PatR
2023-12-08 19:12:38 -08:00
parent cb1eadd6b7
commit 0c88c91c83

View File

@@ -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)
{