#define SAFE_STRNCPY_ZERO_FILL #include #include /* safe_srncpy() is Copyright 1998 by Mark Whitis */ /* All Rights reserved. */ /* use it or distribute it (including for profit) at your own risk */ /* but please don't GPL it. Retain this notice. Modified versions */ /* should be clearly labeled as such. */ char *safe_strncpy(char *dst, char *src, int size) { char *savedst; savedst = dst; /* Make sure destination buffer exists and has positive size */ #ifdef SAFE_STRNCPY_DESTINATION_REQUIRED assert(dst); assert(size>0); #else if(!dst) { errno = EINVAL; return(savedst); } if(size<1) { errno = EINVAL; return(NULL); } #endif /* Do something sensible if we receive a NULL pointer */ #ifdef SAFE_STRNCPY_ABORT_NOSRC assert(src); #else /* treat NULL and "", identically */ if(!src) { dst[0]=0; #ifdef SAFE_STRNCPY_ERROR_NOSRC errno = EINVAL; #endif return(savedst); } #endif size--; /* leave room for trailing zero */ while(*src && ( size-- > 0 ) ) { #ifdef SAFE_STRNCPY_MOVING_ZERO_TERM *(dst+1) = 0; #endif *dst++ = *src++; } *dst = 0; #ifdef SAFE_STRNCPY_ZERO_FILL while( size-- > 0 ) { *dst++ = 0; } #endif /* If we didn't copy the whole string, report error */ if(*src) { errno=ENOSPC; #ifdef SAFE_STRNCPY_ALL_OR_NOTHING /* return zero length string instead of truncated string */ /* on truncation error */ *savedst = 0; #endif } #ifdef SAFE_STRNCPY_TRUNC_ABORT assert(!*src); #endif return(savedst); } main() { char buf[4096]; char sample[]="This is a test. This is only a test"; safe_strncpy(buf,sample,sizeof(buf)); printf("buf=%s\n",buf); buf[25]=0x7A; safe_strncpy(buf,sample,25); printf("buf=%s\n",buf); assert(buf[25]=0x7A); buf[75]=0x7A; safe_strncpy(buf,sample,sizeof(buf)); printf("buf=%s\n",buf); assert(buf[75]!=0x7A); }