Comment by okl
8 days ago
strncpy was originally used to write into fixed length buffers[1]. This becomes obvious when considering the padding behavior, as described in the C standard[2]: "If the array pointed to by s2 is a string that is shorter than n characters, null characters are appended to the copy in the array pointed to by s1, until n characters in all have been written."
strlcpy, often touted as a replacement, does not elicit the padding behavior but has another flaw: It is supposed to return the length of the string it tried to create, for example, so the user can call realloc without calling strlen again.[3] However, this final "strlen-tail" in strlcpy isn't bounded by the size parameter which describes dest, not src.
While strscpy is a marked improvement, there is still something to be careful about: It can read past the end of the src-buffer, when sizeof src < sizeof dest and src is not nul-terminated.[4] (Set the count argument to something like min(sizeof dest, sizeof src) to avoid that).
--
[1] - https://softwareengineering.stackexchange.com/a/438090
[2] - https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf, 7.26.2.5 p. 3
[3] - https://manpages.debian.org/jessie/libbsd-dev/strlcpy.3.en.h...
[4] - https://manpages.debian.org/testing/linux-manual-4.8/strscpy...
> It can read past the end of the src-buffer, when sizeof src < sizeof dest and src is not nul-terminated.
So basically, don't invoke a function "strscpy — Copy a C-string into a sized buffer" on something that is not a C-string. Its description specifically states that it copies a string into a buffer. Compare with the wordings in standard of strcpy ("The strcpy function copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1") and strncpy ("The strncpy function copies not more than n characters (characters that follow a null character are not copied) from the array pointed to by s2 to the array pointed to by s1... If the array pointed to by s2 is a string that is shorter than n characters...").
It's not a function to copy an array into an array (there is memcpy/memmov for that); it's a function to copy a string into an array which, after the function is finished, will certainly be a string (unless it's zero-sized, sigh).