
...
Although the strncpy()
function takes a string as input, it does not guarantee that the resulting value is still null-terminated. In the following noncompliant code example, if no null character is contained in the first n
characters of the source
array, the result will not be null-terminated. Passing a non-null-terminated character sequence to strlen()
is undefined behavior 196.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <string.h> enum { STR_SIZE = 32 }; size_t func(const char *source) { char c_str[STR_SIZE]; size_t ret = 0; if (source) { c_str[sizeof(c_str) - 1] = '\0'; strncpy(c_str, source, sizeof(c_str)); ret = strlen(c_str); } else { /* Handle null pointer */ } return ret; } |
...
Note that this code is not bulletproof. It gracefully handles the case where source
is NULL, when it is a valid string, and when source
is not null-terminated, but at least the first 32 bytes are valid. However, in cases where source
is not NULL, but points to invalid memory, or any of the first 32 bytes are invalid memory, the first call to strnlen()
will will access this invalid memory, and the resulting behavior is undefined. Unfortunately, standard C provides no way to prevent or even detect this condition without some external knowledge about the memory source
points to.
...