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.