]> granicus.if.org Git - nethack/commitdiff
truncating string copy
authornethack.rankin <nethack.rankin>
Tue, 6 Mar 2007 03:00:05 +0000 (03:00 +0000)
committernethack.rankin <nethack.rankin>
Tue, 6 Mar 2007 03:00:05 +0000 (03:00 +0000)
     The majority of our calls to strncpy are in the form
  (void) strncpy(dst, src, n);
  dst[n] = '\0';
so add a new routine, copynchars, which does that.  A few calls care
about strncpy's return value and at least one relies on it only copying a
substring without also terminating the output, but most don't care about
either and none seem to care that `n' ought to have type size_t instead of
int.  The new routine matches our usage better, but I haven't gone through
to change the existing strncpy calls.

include/extern.h
src/hacklib.c
src/questpgr.c

index b0417dee354cd33caa85ed12880ff860f948082d..6c196400250d9e96d63531cab07126c972867c32 100644 (file)
@@ -807,6 +807,7 @@ E char *FDECL(upstart, (char *));
 E char *FDECL(mungspaces, (char *));
 E char *FDECL(eos, (char *));
 E char *FDECL(strkitten, (char *,CHAR_P));
+E void FDECL(copynchars, (char *,const char *,int));
 E char *FDECL(s_suffix, (const char *));
 E char *FDECL(xcrypt, (const char *,char *));
 E boolean FDECL(onlyspace, (const char *));
index 87f69ca6e01fc19cfcad0efe2566d3791f1d9d1c..7231faa676b8840113f11e277486ac15a8634596 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)hacklib.c  3.5     2004/04/11      */
+/*     SCCS Id: @(#)hacklib.c  3.5     2007/03/05      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* Copyright (c) Robert Patrick Rankin, 1991             */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -19,6 +19,7 @@ NetHack, except that rounddiv may call panic().
        char *          mungspaces      (char *)
        char *          eos             (char *)
        char *          strkitten       (char *,char)
+       void            copynchars      (char *,const char *,int)
        char *          s_suffix        (const char *)
        char *          xcrypt          (const char *, char *)
        boolean         onlyspace       (const char *)
@@ -139,6 +140,22 @@ strkitten(s, c)            /* append a character to a string (in place) */
     return s;
 }
 
+void
+copynchars(dst, src, n)                /* truncating string copy */
+    char *dst;
+    const char *src;
+    int n;
+{
+    /* copies at most n characters, stopping sooner if terminator reached;
+       treats newline as input terminator; unlike strncpy, always supplies
+       '\0' terminator so dst must be able to hold at least n+1 characters */
+    while (n > 0 && *src != '\0' && *src != '\n') {
+       *dst++ = *src++;
+       --n;
+    }
+    *dst = '\0';
+}
+
 char *
 s_suffix(s)            /* return a name converted to possessive */
     const char *s;
index 38deef399071be87868f74096afcdd11eedcd612..c5348f11b74d88687eeb7b240da19a6a8c526023 100644 (file)
@@ -476,9 +476,8 @@ deliver_splev_message()
        /* lev_message can span multiple lines using embedded newline chars;
           any segments too long to fit within in_line[] will be truncated */
        for (str = lev_message; *str; str = nl + 1) {
-           (void)strncpy(in_line, str, sizeof in_line - 1);
-           in_line[sizeof in_line - 1] = '\0';
-           if ((nl = index(in_line, '\n')) != 0) *nl = '\0';
+           /* copying will stop at newline if one is present */
+           copynchars(in_line, str, (int)(sizeof in_line) - 1);
 
            /* convert_line() expects encrypted input;
               it reads from in_line[] and writes to out_line[] */