From: PatR Date: Mon, 28 Dec 2015 01:43:58 +0000 (-0800) Subject: death-reason sanitizing X-Git-Tag: NetHack-3.6.1_RC01~1104 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e43e97b021365cc126f4315ede66c62a74eb573c;p=nethack death-reason sanitizing Prevent commas, equal signs, and tabs in reason for death. Comma can make while-helpless reason ambiguous in record and basic logfile. Equal sign can do the same for fixrecord.awk, the awk program that can be used to fix up corrupted 3.6.0 record files, if it resorts to constructing logfile records out of xlogfile records. And tab could break parsing of xlogfile (it should already be excluded though; the code that lets players assign names to monsters uses mungspaces(), and one of the things that does is to convert any tab into a space before squeezing consecutive spaces down to one). The name alteration shows up for tombstone as well as for file entries. That could be changed but hardly seems worth the effort. Perhaps the name sanitizing ought to be moved to the initial naming? At least then it would be pretty obvious that it was intentional rather by mistake. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index f8c07baaa..f3881c599 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -68,6 +68,8 @@ fix message typo if tame mind flayer dies trying to eat Medusa's brains use alternate rejection message if attempting to name an unnameable monster with the name it already has cockatrice corpse no longer leaves multiple statues for shape-shifted vampire +alter name of monster causing hero's death if name contains characters that + could cause confusion when using record, logfile, or xlogfile later Platform- and/or Interface-Specific Fixes diff --git a/src/topten.c b/src/topten.c index 9af1d54df..4056d2ac6 100644 --- a/src/topten.c +++ b/src/topten.c @@ -100,9 +100,9 @@ boolean incl_helpless; "", "", "", "", "" }; unsigned l; - char *kname = killer.name; + char c, *kname = killer.name; - buf[0] = '\0'; /* so strncat() can find the end */ + buf[0] = '\0'; /* lint suppression */ switch (killer.format) { default: impossible("bad killer format? (%d)", killer.format); @@ -118,13 +118,30 @@ boolean incl_helpless; buf += l, siz -= l; break; } - /* we're writing into buf[0] (after possibly advancing buf) rather than - appending, but strncat() appends a terminator and strncpy() doesn't */ - (void) strncat(buf, kname, siz - 1); + /* Copy kname into buf[]. + * Object names and named fruit have already been sanitized, but + * monsters can have "called 'arbitrary text'" attached to them, + * so make sure that that text can't confuse field splitting when + * record, logfile, or xlogfile is re-read at some later point. + */ + while (--siz > 0) { + c = *kname++; + if (c == ',') + c = ';'; + /* 'xlogfile' doesn't really need protection for '=', but + fixrecord.awk for corrupted 3.6.0 'record' does (only + if using xlogfile rather than logfile to repair record) */ + else if (c == '=') + c = '_'; + /* tab is not possible due to use of mungspaces() when naming; + it would disrupt xlogfile parsing if it were present */ + else if (c == '\t') + c = ' '; + *buf++ = c; + } + *buf = '\0'; if (incl_helpless && multi) { - siz -= strlen(buf); - buf = eos(buf); /* X <= siz: 'sizeof "string"' includes 1 for '\0' terminator */ if (multi_reason && strlen(multi_reason) + sizeof ", while " <= siz) Sprintf(buf, ", while %s", multi_reason);