fix #H620 - dangerous/disruptive strings in bones data

It's possible for the player to put escape sequences into strings via
dogname/catname/fruit options (or probably interactively by using "\233"
instead of "\033["--the two character 7-bit version wouldn't work because
its leading ESC gets treated as player's request to abort current input,
but the 8-bit version probably works, I just can't test it because I don't
know how to type such things with this terminal emulator).  Such sequences
can do funny things like clear the screen and say "game over" (or worse
with creative abuse of some terminals' "answer back" capability--when
reproducing the reported situation, I kept things simple and had my dog's
name underlined and fruit name blinking; they displayed correctly but
nethack was confused about how long they were since it doesn't expect to
be given characters which don't advance the cursor).  This fix still lets
users experiment with such stuff during their own games, but it replaces
suspect characters while loading bones data, so if one player creates a
bones file with suspect strings in it, another can--I hope--be able to
use that file safely.

     Monster and object names, engravings, and named fruits are handled.
For the last, if uncensored string matches one already present then it
leaves that alone, so bones data created with same OPTIONS=fruit:whatever
as being used in the current game will continue to keep the same value.
This commit is contained in:
nethack.rankin
2007-06-29 01:18:51 +00:00
parent 7333ca4705
commit f847518f4a
5 changed files with 57 additions and 4 deletions

View File

@@ -82,6 +82,8 @@ boolean restore;
} else {
artifact_exists(otmp, safe_oname(otmp), TRUE);
}
} else if (has_oname(otmp)) {
sanitize_name(ONAME(otmp));
}
} else { /* saving */
/* do not zero out o_ids for ghost levels anymore */
@@ -169,6 +171,33 @@ boolean restore;
}
}
/* while loading bones, strip out text possibly supplied by old player
that might accidentally or maliciously disrupt new player's display */
void
sanitize_name(namebuf)
char *namebuf;
{
int c;
boolean strip_8th_bit = !strcmp(windowprocs.name, "tty") &&
!iflags.wc_eight_bit_input;
/* it's tempting to skip this for single-user platforms, since
only the current player could have left these bones--except
things like "hearse" and other bones exchange schemes make
that assumption false */
while (*namebuf) {
c = *namebuf & 0177;
if (c < ' ' || c == '\177') {
/* non-printable or undesireable */
*namebuf = '.';
} else if (c != *namebuf) {
/* expected to be printable if user wants such things */
if (strip_8th_bit) *namebuf = '_';
}
++namebuf;
}
}
/* called by savebones(); also by finish_paybill(shk.c) */
void
drop_upon_death(mtmp, cont, x, y)
@@ -498,6 +527,7 @@ getbones()
* set to the magic DEFUNCT_MONSTER cookie value.
*/
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (has_mname(mtmp)) sanitize_name(MNAME(mtmp));
if (mtmp->mhpmax == DEFUNCT_MONSTER) {
#if defined(DEBUG) && defined(WIZARD)
if (wizard)
@@ -514,6 +544,7 @@ getbones()
}
}
(void) close(fd);
sanitize_engravings();
#ifdef WIZARD
if(wizard) {