3 ms·
A big footgun with strncpy is that the output string may not be null terminated.
by ufo 9mo ago
A big footgun with strncpy is that the output string may not be null terminated.
- kccqzy 9mo agoYeah but fixed width strings don’t need null termination. You know exactly how long the string is. No need to find that null byte.
- ninkendo 9mo agoUntil you pass them as a `char *` by accident and it eventually makes its way to some code that does expect null termination. There’s languages where you can be quite confident your string will never need null termination… but C is not one of them.
- deleted 9mo ago[deleted]
- kccqzy 9mo agoYou don’t do that by accident. Fixed-width strings are thoroughly outdated and unusual. Your mental model of them is very different from regular C strings.
- arka2147483647 9mo agoSadly, all the bug trackers are full of bugs relating to char*. So you very much do those by accident. And in C, fixed width strings are not in any way rare or unusual. Go to any c codebase you will find stuff like: char buf[12]; sprintf(buf, "%s%s", this, that); // or strcat(buf, ...) // or strncpy(buf, ...) // and so on..
- snickerbockers 9mo agoThats only really a problem if this and that are coming from an external source and have not been truncated. I really don't see this as any more significant of a problem than all the many high level scripting languages where you can potentially inject code into a variable and interpret it. There are certainly ways in which the c library could've been better (eg making strncpy handle the case where the source string is longer than n) but ultimately it will always need to operate under the assumption that the people using it are both competent and acting in good faith.
- kccqzy 9mo agoWhen you write such code your mental model is C strings, not fixed-width strings, the intended use case for strncpy.
- ninkendo 9mo agoThe mental model doesn’t matter, it’s the compiler’s model that is going to bite you. If the compiler doesn’t reject it, it will happen eventually.
- Sharlin 9mo agoGood luck though remembering not to pass one to any function that does expect to find a null terminator.
- andrepd 9mo agoSeriously. We have type systems and compilers that help us to not forget these things. It's not the 70s anymore!
- deleted 9mo ago[deleted]
- kevin_thibedeau 9mo agoIgnore the prefix and always treat strncpy() as a special binary data operation for an era where shaving bytes on storage was important. It's for copying into a struct with array fields or direct to an encoded block of memory. In that context you will never be dependent on the presence of NUL. The only safe usage with strings is to check for NUL on every use or wrap it. At that point you may as well switch to a new function with better semantics.
- masklinn 9mo ago> an era where shaving bytes on storage was important Fixed size strings don’t save bytes on storage tho, when the bank reserves 20 bytes for first name and you’re called Jon that’s 17 bytes doing fuckall. What they do is make the entire record fixed size and give every field a fixed relative position so it’s very easy to access items, move record around, reuse allocations (or use static allocation), … cycles is what they save.
- josefx 9mo ago> Fixed size strings don’t save bytes on storage tho I have seen plenty of fixed strings in the 8 to 20 byte range, not much, but often enough for a passable identifier. The memory management overhead for a simple dynamically allocated string is probably larger than that even on a 32 bit system.