When people say, "strcpy()
is dangerous, use strncpy()
instead" (or similar statements about strcat()
etc., but I am going to use strcpy()
here as my focus), they mean that there is no bounds checking in strcpy()
. Thus, an overly long string will result in buffer overruns. They are correct. Using strncpy()
in this case will prevent buffer overruns.
I feel that strncpy()
really doesn't fix bugs: it solves a problem that can be easily avoided by a good programmer.
As a C programmer, you must know the destination size before you are trying to copy strings. That is the assumption in strncpy()
and strlcpy()
's last parameters too: you supply that size to them. You can also know the source size before you copy strings. Then, if the destination is not big enough, don't call strcpy()
. Either reallocate the buffer, or do something else.
Why do I not like strncpy()
?
strncpy()
is a bad solution in most cases: your string is going to be truncated without any notice—I would rather write extra code to figure this out myself and then take the course of action that I want to take, rather than let some function decide for me about what to do.
strncpy()
is very inefficient. It writes to every byte in the destination buffer. You don't need those thousands of '\0'
at the end of your destination.
- It doesn't write a terminating
'\0'
if the destination is not big enough. So, you must do so yourself anyway. The complexity of doing this is not worth the trouble.
Now, we come to strlcpy()
. The changes from strncpy()
make it better, but I am not sure if the specific behavior of strl*
warrants their existence: they are far too specific. You still have to know the destination size. It is more efficient than strncpy()
because it doesn't necessarily write to every byte in the destination. But it solves a problem that can be solved by doing: *((char *)mempcpy(dst, src, n)) = 0;
.
I don't think anyone says that strlcpy()
or strlcat()
can lead to security issues, what they (and I) are saying that they can result in bugs, for example, when you expect the complete string to be written instead of a part of it.
The main issue here is: how many bytes to copy? The programmer must know this and if he doesn't, strncpy()
or strlcpy()
won't save him.
strlcpy()
and strlcat()
are not standard, neither ISO C nor POSIX. So, their use in portable programs is impossible. In fact, strlcat()
has two different variants: the Solaris implementation is different from the others for edge cases involving length 0. This makes it even less useful than otherwise.
strlcpy
andstrlcat
would report some sort of error condition if they bumped against the destination buffer size limit. Though you can check the returned length to test this, it's not obvious. But I think that's a minor criticism. The 'they encourage the use of C strings, and so they are bad' argument is silly. – Nichollenicholls