Safe Programming with strncpy and strlen
Alexander Liss
06/14/01
If one uses
strncpy(char d, char s, int limit)
or
strlen(char *s),
one can encounter situations, which lead to difficult to detect bugs.
With strnlen, when a length of string s is larger than limit, limit bytes are copied and d[limit] byte is set to zero (!).
With strlen, when an argument points to a byte array, which is not properly terminated with zero, the function can loop too far, trying to find a first zero.
There is a simple technique, which allows avoiding this kind of problems.
First step is with buffers allocation.
Usually a buffer is allocated on stack as char * buffer[BUFFER_SIZE]; where
BUFFER_SIZE
is defined somewhere. It is better to define it as
char * buffer[BUFFER_SIZE+1];
and immediately initialize this buffer, for example
memset(buffer,0,sizeof(buffer));
(a function
int init_buffer(char *z){ return memset(z,0,sizeof(z));}
can be helpful).
As a limit, we still use
BUFFER_SIZE
or
sizeof(buffer) –1,
as in
strncpy(buffer, str, sizeof(buffer) –1);
This pattern has to be carefully followed, because bad bugs occur, when a buffer is allocated in one function and it is used in another (called) function and these functions definitions are far apart in source code.