From 5a874440a07b3a59bfec58042261e5f1b0278a42 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Tue, 6 Mar 2007 03:00:05 +0000 Subject: [PATCH] truncating string copy 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 | 1 + src/hacklib.c | 19 ++++++++++++++++++- src/questpgr.c | 5 ++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index b0417dee3..6c1964002 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *)); diff --git a/src/hacklib.c b/src/hacklib.c index 87f69ca6e..7231faa67 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -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; diff --git a/src/questpgr.c b/src/questpgr.c index 38deef399..c5348f11b 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -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[] */