fix default engraving/epitaph/bogusmon corruption

Fixes #369.
Fixes #370.

The default entries inserted by makedefs -s (starting in 3.6.6,
to guard against having an empty data file which led to divide by
zero crash when nethack picked a random entry) lacked a terminating
newline so the first entry from the file (for the usual case when
that data file wasn't empty) got implicitly concatenated to it.
If the first entry got chosen during play, the initial portion
corresponding to the default entry was decrypted properly but the
concatenated portion corresponding to file's first line didn't.
So gibberish was appended to default engraving or epitaph or bogus
monster; also, the input file's first line would never appear.

The newline fix in makedefs is different from pull request #370
but accomplishes the same thing.

The bulk of the patch is an enhancement to #wizrumorcheck to show
first (default inserted by makedefs), second (first in input file)
and last engravings, epitaphs, and bogusmons in addition to rumors.
The command name has become a little misleading but the limited
functionality doesn't call for separate commands.
This commit is contained in:
PatR
2020-07-09 19:23:19 -07:00
parent 63842b64ef
commit 0bd2c3154d
5 changed files with 144 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.389 $ $NHDT-Date: 1594118318 2020/07/07 10:38:38 $
.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.390 $ $NHDT-Date: 1594347794 2020/07/10 02:23:14 $
.\"
.\" This is an excerpt from the 'roff' man page from the 'groff' package.
.\" Guidebook.mn currently does *not* fully adhere to these guidelines.
@@ -35,7 +35,7 @@
.ds vr "NetHack 3.7
.ds f0 "\*(vr
.ds f1
.ds f2 "July 5, 2020
.ds f2 "July 9, 2020
.
.\" A note on some special characters:
.\" \(lq = left double quote
@@ -1554,7 +1554,12 @@ Autocompletes.
Debug mode only.
Default key is \(oq\(haF\(cq.
.lp #wizrumorcheck
Verify rumor boundaries.
Verify rumor boundaries by displaying first and last true rumors and
first and last false rumors.
.lp ""
Also displays first, second, and last random engravings, epitaphs,
and hallucinatory monsters.
.lp ""
Autocompletes.
Debug mode only.
.lp #wizsmell

View File

@@ -45,7 +45,7 @@
%.au
\author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.7 by Mike Stephenson and others)}
\date{July 5, 2020}
\date{July 9, 2020}
\maketitle
@@ -1650,7 +1650,12 @@ Debug mode only.
Default key is `{\tt \^{}F}'.
%.lp
\item[\tb{\#wizrumorcheck}]
Verify rumor boundaries.
Verify rumor boundaries by displaying first and last true rumors and
first and last false rumors.\\
%.lp ""
Also displays first, second, and last random engravings, epitaphs,
and hallucinatory monsters.\\
%.lp ""
Autocompletes.
Debug mode only.
%.lp

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.240 $ $NHDT-Date: 1593772051 2020/07/03 10:27:31 $
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ $NHDT-Date: 1594347794 2020/07/10 02:23:14 $
General Fixes and Modified Features
-----------------------------------
@@ -211,6 +211,11 @@ reading non-cursed Book of the Dead without having prepped the other tools
zapping a line of boulders with striking or force bolt was updating 'couldsee'
but deferring 'cansee', resulting in seeing the first boulder fracture
and only hearing that happen for the others despite coming into view
the default engraving, epitaph, and bogus monster inserted by 'makedefs -s'
(3.6.6 fix for empty source data file) lacked terminating newline, so
when the corresponding file wasn't actually empty its first line ended
up concatenated; default portion of the bad combined entry would be
decrypted properly but the portion from the file's first line wouldn't
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 rumors.c $NHDT-Date: 1583445339 2020/03/05 21:55:39 $ $NHDT-Branch: NetHack-3.6-Mar2020 $:$NHDT-Revision: 1.38 $ */
/* NetHack 3.7 rumors.c $NHDT-Date: 1594347790 2020/07/10 02:23:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -42,6 +42,7 @@
static void FDECL(init_rumors, (dlb *));
static void FDECL(init_oracles, (dlb *));
static void FDECL(others_check, (const char *ftype, const char *, winid *));
static void FDECL(couldnt_open_file, (const char *));
static void
@@ -166,14 +167,13 @@ boolean exclude_cookie;
return rumor_buf;
}
/*
* test that the true/false rumor boundaries are valid.
*/
/* test that the true/false rumor boundaries are valid and show the first
two and very last epitaphs, engravings, and bogus monsters */
void
rumor_check()
{
dlb *rumors = 0;
winid tmpwin;
winid tmpwin = WIN_ERR;
char *endp, line[BUFSZ], xbuf[BUFSZ], rumor_buf[BUFSZ];
if (g.true_rumor_size < 0L) { /* we couldn't open RUMORFILE */
@@ -183,7 +183,6 @@ rumor_check()
}
rumors = dlb_fopen(RUMORFILE, "r");
if (rumors) {
long ftell_rumor_start = 0L;
@@ -257,12 +256,122 @@ rumor_check()
putstr(tmpwin, 0, rumor_buf);
(void) dlb_fclose(rumors);
display_nhwindow(tmpwin, TRUE);
destroy_nhwindow(tmpwin);
} else {
couldnt_open_file(RUMORFILE);
g.true_rumor_size = -1; /* don't try to open it again */
}
/* initial implementation of default epitaph/engraving/bogusmon
contained an error; check those along with rumors */
others_check("Engravings:", ENGRAVEFILE, &tmpwin);
others_check("Epitaphs:", EPITAPHFILE, &tmpwin);
others_check("Bogus monsters:", BOGUSMONFILE, &tmpwin);
if (tmpwin != WIN_ERR) {
display_nhwindow(tmpwin, TRUE);
destroy_nhwindow(tmpwin);
}
}
/* 3.7: augments rumors_check(); test 'engrave' or 'epitaph' or 'bogusmon' */
static void
others_check(ftype, fname, winptr)
const char *ftype, *fname;
winid *winptr;
{
static const char errfmt[] = "others_check(\"%s\"): %s";
dlb *fh;
char line[BUFSZ], xbuf[BUFSZ], *endp;
winid tmpwin = *winptr;
int entrycount = 0;
fh = dlb_fopen(fname, "r");
if (fh) {
if (tmpwin == WIN_ERR) {
*winptr = tmpwin = create_nhwindow(NHW_TEXT);
if (tmpwin == WIN_ERR) {
/* should panic, but won't for wizard mode check operation */
impossible(errfmt, fname, "can't create temporary window");
goto closeit;
}
}
putstr(tmpwin, 0, "");
putstr(tmpwin, 0, ftype);
/* "don't edit" comment */
*line = '\0';
if (!dlb_fgets(line, sizeof line, fh)) {
Sprintf(xbuf, errfmt, fname, "error; can't read comment line");
putstr(tmpwin, 0, xbuf);
goto closeit;
}
if (*line != '#') {
Sprintf(xbuf, errfmt, fname,
"malformed; first line is not a comment line:");
putstr(tmpwin, 0, xbuf);
/* show the bad line; we don't know whether it has been
encrypted via xcrypt() so show it both ways */
if ((endp = index(line, '\n')) != 0)
*endp = 0;
putstr(tmpwin, 0, "- first line, as is");
putstr(tmpwin, 0, line);
putstr(tmpwin, 0, "- xcrypt of first line");
putstr(tmpwin, 0, xcrypt(line, xbuf));
goto closeit;
}
/* first line; should be default one inserted by makedefs when
building the file but we don't have the expected value so
can only require a line to exist */
*line = '\0';
if (!dlb_fgets(line, sizeof line, fh) || *line == '\n') {
Sprintf(xbuf, errfmt, fname,
!*line ? "can't read first non-comment line"
: "first non-comment line is empty");
putstr(tmpwin, 0, xbuf);
goto closeit;
}
++entrycount;
if ((endp = index(line, '\n')) != 0)
*endp = 0;
putstr(tmpwin, 0, xcrypt(line, xbuf));
if (!dlb_fgets(line, sizeof line, fh)) {
putstr(tmpwin, 0, "(no second entry)");
} else {
++entrycount;
if ((endp = index(line, '\n')) != 0)
*endp = 0;
putstr(tmpwin, 0, xcrypt(line, xbuf));
while (dlb_fgets(line, sizeof line, fh)) {
++entrycount;
if ((endp = index(line, '\n')) != 0)
*endp = 0;
(void) xcrypt(line, xbuf);
}
/* count will be 2 if the default entry and the first ordinary
entry are the only ones present (if either of those were
missing, we wouldn't have gotten here...) */
if (entrycount == 2) {
putstr(tmpwin, 0, "(only two entries)");
} else {
/* showing an elipsis three times (once for each file)
results in total size being 24 lines, forcing a
--More-- prompt if user only has a 24 line screen;
that doesn't look very good but isn't incorrect;
including it avoids ambiguity about whether there
are other lines */
if (entrycount > 3)
putstr(tmpwin, 0, " ...");
putstr(tmpwin, 0, xbuf); /* already decrypted */
}
}
closeit:
(void) dlb_fclose(fh);
} else {
/* since this comes out via impossible(), it won't be integrated
with the text window of values, but it shouldn't ever happen
so we won't waste effort integrating it */
couldnt_open_file(fname);
}
}
/* Gets a random line of text from file 'fname', and returns it.

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 makedefs.c $NHDT-Date: 1587503038 2020/04/21 21:03:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */
/* NetHack 3.6 makedefs.c $NHDT-Date: 1594347789 2020/07/10 02:23:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */
/* Copyright (c) M. Stephenson, 1990, 1991. */
@@ -939,7 +939,7 @@ do_rnd_access_file(fname, deflt_content)
const char *fname;
const char *deflt_content;
{
char *line;
char *line, buf[BUFSZ];
Sprintf(filename, DATA_IN_TEMPLATE, fname);
Strcat(filename, ".txt");
@@ -957,6 +957,10 @@ const char *deflt_content;
exit(EXIT_FAILURE);
}
Fprintf(ofp, "%s", Dont_Edit_Data);
/* lines from the file include trailing newline so make sure that the
default one does too */
if (!index(deflt_content, '\n'))
deflt_content = strcat(strcpy(buf, deflt_content), "\n");
/* write out the default content entry unconditionally instead of
waiting to see whether there are no regular output lines; if it
matches a regular entry (bogusmon "grue"), that entry will become