Re:C Strings and my slow descent to madness
by saagarjha on Friday April 07, 2023 @10:55PM
(#35490034)
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.)
Re:C Strings and my slow descent to madness
by anthomtb on Saturday April 08, 2023 @01:33PM
(#35495623)
Look at the declarations:
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
size_t strlcpy(char *dest, const char *src, size_t size);
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.
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.