From 1f6d5e4afb4e84cea4a0c35cbbcd2eed8c1a533b Mon Sep 17 00:00:00 2001 From: Richard Russon Date: Tue, 4 Oct 2016 13:19:09 +0100 Subject: [PATCH] fix: strfcpy() improvement A quick string copying history. In the beginning was: strcpy (DST, SRC); If the SRC was bigger than DST, then bad things happened. Then came: strncpy (DST, SRC, LEN); If SRC is longer than LEN, then the string in DST isn't NULL terminated. Bad things happened. Next, Mutt created a macro strfcpy() based on the BSD function. It guarantees a length limit AND a NULL termination. #define strfcpy(DST,SRC,LEN) strncpy(DST,SRC,LEN), *(DST+(LEN)-1)=0 Because of the way it works, it triggers a warning in Coverity (a static analysis tool). It fills DST (without NULL), then writes the NULL. My testing shows it works correctly, but I may missed something. #define strfcpy(DST,SRC,LEN) do { if ((LEN) > 0) { *(DST+(LEN)-1)=0; strncpy(DST,SRC,(LEN)-1); } } while (0) --- dotlock.c | 2 +- lib.h | 2 +- rfc822.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dotlock.c b/dotlock.c index dc143966b..56a2bae66 100644 --- a/dotlock.c +++ b/dotlock.c @@ -63,7 +63,7 @@ # define LONG_STRING 1024 # define MAXLOCKATTEMPT 5 -# define strfcpy(A,B,C) strncpy (A,B,C), *(A+(C)-1)=0 +#define strfcpy(DST,SRC,LEN) do { if ((LEN) > 0) { *(DST+(LEN)-1)=0; strncpy(DST,SRC,(LEN)-1); } } while (0) # ifdef USE_SETGID diff --git a/lib.h b/lib.h index 84d33b5e7..c048f8cc1 100644 --- a/lib.h +++ b/lib.h @@ -77,7 +77,7 @@ # define FREE(x) safe_free(x) # define NONULL(x) x?x:"" # define ISSPACE(c) isspace((unsigned char)c) -# define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0 +# define strfcpy(DST,SRC,LEN) do { if ((LEN) > 0) { *(DST+(LEN)-1)=0; strncpy(DST,SRC,(LEN)-1); } } while (0) # undef MAX # undef MIN diff --git a/rfc822.c b/rfc822.c index d347d69e8..6114a1aa3 100644 --- a/rfc822.c +++ b/rfc822.c @@ -30,7 +30,7 @@ #define safe_strdup strdup #define safe_malloc malloc #define FREE(x) safe_free(x) -#define strfcpy(a,b,c) {if (c) {strncpy(a,b,c);a[c-1]=0;}} +#define strfcpy(DST,SRC,LEN) do { if ((LEN) > 0) { *(DST+(LEN)-1)=0; strncpy(DST,SRC,(LEN)-1); } } while (0) #define LONG_STRING 1024 #include "rfc822.h" #endif -- 2.40.0