Advertisements
Avoiding buffer overflows - strlcpy and strlcat
It is not wise to use the ANSI standard strcpy and strcat functions because of the possibility of unchecked buffer overflows. The strncpy function has the problem that it may not properly terminate the string. The following strlcpy and strlcat functions are simple implementations that overcome the problems of their original ANSI ancestors (last updated 2011-12-11).
#include <string.h>
size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len;
size_t ret;
if (!d || !s || (int)bufsize <= 0) return 0;
len = strlen(s);
ret = len;
if (len >= bufsize) len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
return ret;
}
size_t strlcat(char *d, const char *s, size_t bufsize)
{
size_t len1;
size_t len2;
size_t ret;
if (!d || !s || (int)bufsize <= 0) return 0;
len1 = strlen(d);
len2 = strlen(s);
ret = len1 + len2;
if (len1+len2 >= bufsize)
len2 = bufsize - (len1 + 1);
if (len2 > 0)
{
memcpy(d+len1, s, len2);
d[len1+len2] = 0;
}
return ret;
}
These functions are guaranteed not to cause a buffer overflow and the result is always null-terminated. If there is not enough room in the destination buffer, then it truncates the output. The return value is the number of bytes it should have copied, so you have a roundabout way of checking. The value of bufsize is the actual allocated size of the buffer, so you can use sizeof(buf) (providing buf is not a pointer).
For more on the background to these functions see strlcpy and strlcat - consistent, safe, string copy and concatenation by Todd C. Miller and Theo de Raadt.
The above solutions do have the disadvantage that they always do at least a double pass along the strings, and so are only half as efficient as the originals which don't. This is really only a problem for very long strings.
We've never noticed any performance issue in practice with this code. It's far, far more important that we know we can use these functions in our applications safe in the knowledge that we will not get a buffer overflow problem, and that we won't be getting people writing in to say they got a run-time error with our program and can they have their money back. If it's really important that there is no truncation, then do your own pre-condition checks and call the raw <string.h> function.