]> granicus.if.org Git - nethack/commitdiff
death-reason sanitizing
authorPatR <rankin@nethack.org>
Mon, 28 Dec 2015 01:43:58 +0000 (17:43 -0800)
committerPatR <rankin@nethack.org>
Mon, 28 Dec 2015 01:43:58 +0000 (17:43 -0800)
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.

doc/fixes36.1
src/topten.c

index f8c07baaa2f1a9798597b5d1536f7db906e10da5..f3881c599aa4098a2c9f46a40f93e000bb0d4e5f 100644 (file)
@@ -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
index 9af1d54dfd68a3244b2fd526953047f035c21f34..4056d2ac6fce145090384e231085272c5fcaa5d5 100644 (file)
@@ -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);