cstrncpy

Why does strncpy not null terminate?


strncpy() supposedly protects from buffer overflows. But if it prevents an overflow without null terminating, in all likelihood a subsequent string operation is going to overflow. So to protect against this I find myself doing:

strncpy( dest, src, LEN );
dest[LEN - 1] = '\0';

man strncpy gives:

The strncpy() function is similar, except that not more than n bytes of src are copied. Thus, if there is no null byte among the first n bytes of src, the result will not be null-terminated.

Without null terminating something seemingly innocent like:

   printf( "FOO: %s\n", dest );

...could crash.


Are there better, safer alternatives to strncpy()?


Solution

  • strncpy() is not intended to be used as a safer strcpy(), it is supposed to be used to insert one string in the middle of another.

    All those "safe" string handling functions such as snprintf() and vsnprintf() are fixes that have been added in later standards to mitigate buffer overflow exploits etc.

    Wikipedia mentions strncat() as an alternative to writing your own safe strncpy():

    *dst = '\0';
    strncat(dst, src, LEN);
    

    EDIT

    I missed that strncat() exceeds LEN characters when null terminating the string if it is longer or equal to LEN char's.

    Anyway, the point of using strncat() instead of any homegrown solution such as memcpy(..., strlen(...))/whatever is that the implementation of strncat() might be target/platform optimized in the library.

    Of course you need to check that dst holds at least the nullchar, so the correct use of strncat() would be something like:

    if (LEN) {
        *dst = '\0'; strncat(dst, src, LEN-1);
    }
    

    I also admit that strncpy() is not very useful for copying a substring into another string, if the src is shorter than n char's, the destination string will be truncated.