which to me will help with some of these issues. Too bad other Operating Systems do not have these. On Linux there is libbsd to get these, but I would like to see these to be added to the stdc.
Instead the c23 standard is messing with realloc(3) which could break some old programs. I have not looked at that in detail yet, so maybe it is a non-issue :)
These functions are in the current POSIX draft - though not published, it's quite unlikely to be removed (someone actually specifically filed an issue against POSIX to try and get it removed, basically on the basis of "it's not perfect so it should be removed", and the issue got rejected on the basis that there's no consensus for removal, and it seems unlikely this will change), and as a result, the functions are getting added to glibc: https://sourceware.org/pipermail/libc-alpha/2023-April/14696...
I don't know of a compiler that forces you to use the newest version of the standard, which is why I've always kind of thought "don't break old code" was treated too much like dogma. So from that perspective, a non issue.
However, there is a problem that has nothing to do with old code: they increased the number of situations that constitute undefined behavior, with no public discussion and no justification. It's frankly dangerous behavior.
strlcpy is nice due to the guaranteed NUL termination.
strlcpy is not so nice due to the strange (IMO) return value of the number of characters in the source string. Which could be the number of characters copied or much, much larger than the number of characters copied. snprintf does the same thing.
So using strlcpy is safe (by C's low bar) but using the return value may be highly unsafe.
The thing that annoys me the most about strlcpy is that it is supposed to be safer, but what happens in the case where the source string is not properly NULL terminated? You might think that it will stop at the character limit you specified, but that's not what it does. It just blows on past the end of the buffer looking for a \0 until it either finds one or causes a segmentation violation.
IMHO I would like it much more if the return values were:
0: string copied
1: string partially copied but truncated
-1: Error, errno set. This can occur when src or dst are NULL.
None of strlcpy, strncpy, and strcpy will know that you have not provided a string. They will assume the source pointer is a string and as such, will read (and write, in the case of strcpy) bytes until they find that NUL.
This is the upside of strlcpy. Whatever is in your output buffer is guaranteed to be a NUL terminated and have your desired length. strncpy does not make that guarantee. strcpy will give you something with a NUL terminator but it could be well past the end of the output buffer. Hello, CVE.
The more I write here, the more I realize how silly it would be to write anything dealing with human-readable text in C in 2023. I had been working on a C webserver a while back but I think I'm going to purge that from my local git server and start over with something else.
Passing something that is not a string to strcpy or strlcpy is undefined behavior. They operate on strings, which are null-terminated by definition. On the flip side, strncpy operates on character arrays, which do not have to be null-terminated. (This is also why the output buffer is not always null-terminated: it's not meant to represent a string, despite the highly confusing str- prefix.)
From that, how do you know that strncpy expects and produces a character array, strcpy expects and produces a string, and strlcpy takes either a character array or string and produces a string?
Your descriptions of the string/character copy functions are factual and accurate. But correct use depends on programmer understanding. You do not get any runtime guarantee. And IME, when you are under a deadline, 13 function calls and 3 message queues deep in some ancient codebase, while trying to get a non-trivial feature working, the distinction between a character array and a string is easily forgotten.
Anyways, my assertions are:
1) Using C for strings is a poor choice
2) If your compiler vendor or cranky boss forces use of C, use strlcpy to handle string copying.
Yup, there is also Linux's strscpy which doesn't require reading memory from the source string beyond the specified "count" bytes and the return value is idiot proof.
https://man.openbsd.org/strlcpy.3
https://man.openbsd.org/wcslcpy.3
which to me will help with some of these issues. Too bad other Operating Systems do not have these. On Linux there is libbsd to get these, but I would like to see these to be added to the stdc.
Instead the c23 standard is messing with realloc(3) which could break some old programs. I have not looked at that in detail yet, so maybe it is a non-issue :)