News for hackers. Stuff that matters.
Re:Massacring C Pointers by simias on Tuesday June 26, 2018 @08:37AM (#17400045)
I'm not saying it's hard to work around but I maintain it's broken. You have a function that deals with C-string that in some conditions returns something that's not a C-string but can't be trivially distinguished from one and will trigger undefined behavior if used like one. It's terrible ergonomics and almost certainly not what you want to do in any situation.

You can argue that truncation is an error condition but then it ought to notify it somehow, for instance by returning NULL in such a case. And even then it's incoherent with snprintf which doesn't have the same behaviour and does always terminate with '\0' even in case of truncation (assuming non-0 buffer length, of course).

It's just an unnecessary footgun that serves no practical purpose. It would be like a date function that gives you the today's date except on the 4th of December where it replies that it's the 31st of February. Not hard to work around but still broken.

Re:Massacring C Pointers by caf on Tuesday June 26, 2018 @09:39AM (#17400459)
It's not broken, but it is misnamed.

This is because it is not intended to work with the same kind of string that the other str* functions work with (ie. an ordinary null terminated string).

Instead it's supposed to work with fixed-width string fields that pad out values shorter than the field width with nulls. This is how original UNIX directory entries were stored.

See how the name is copied into u.u_dbuf here: https://github.com/hephaex/unix-v6/blob/daa355109625a50e6b10...

Re:Massacring C Pointers by simias on Tuesday June 26, 2018 @10:37AM (#17400885)
I see your point but at this point I think it's just a matter of taste. I don't really see how having a function meant to deal with a special case of character buffers disguised as a general purpose string manipulation routine in the stdlib could be considered reasonable. I understand why it's here, I understand the history, I understand why it made sense at some point to have such a function but you won't be able to convince me that it's not broken or that it shouldn't be deprecated in favor of strlcpy (ditto for strncat/strlcat). After all it is in <string.h>, not <fixed-width-string.h>, it's pretty heinous that it fails at the very low bar of actually producing a valid C string every time (especially given the very high prejudice of having rogue unterminated "strings" in a C program).
Re:Massacring C Pointers by caf on Wednesday June 27, 2018 @02:01AM (#17406070)
It seems fairly unlikely that the C standard would add strlcpy() and strlcat() when it already has strcpy_s() and strcat_s() in Annex K.
Re:Massacring C Pointers by heisenbit on Tuesday June 26, 2018 @02:02PM (#17402757)
A misname that may have cost cost billions in bugs and security issues.
Re:Massacring C Pointers by burfog on Tuesday June 26, 2018 @11:22PM (#17405548)
It has also avoided security issues, some of which get created when people get the idea that every strncpy must be replaced by strlcpy.

The strncpy function writes to the entire buffer. This is important if you will be passing the buffer across a security boundary, for example in a network packet or as a struct copied into a publicly visible file. If trailing bytes are not cleared, then secret data (which happened to be sitting in memory) can get leaked.

Re:Massacring C Pointers by dxhdr on Tuesday June 26, 2018 @11:31AM (#17401372)
I agree it's terribly named, however discussing the behavior of strncpy is important because the casual reader or new C programmer will see "don't use strncpy, it's broken" and then come away with the wrong idea. strncpy is not inherently broken but it's most likely not the correct function to use. As a C programmer it's important to understand why and what the alternatives are (and there are several).
Re:Massacring C Pointers by jschwartzi on Tuesday June 26, 2018 @01:22PM (#17402438)
I can use a sledgehammer to break my leg, but that doesn't mean the hammer is broken by design. I just have to be careful where I swing the hammer and what I hit with it.
Re:Massacring C Pointers by simias on Tuesday June 26, 2018 @01:36PM (#17402565)
If the sledgehammer defaults to "leg breaking mode" then it's broken. How often do you actually use strncpy actually intending it not to return a non-NUL terminated string on truncation?

I hate this mentality in a lot of C circles that boils down to "there's no bad language, just bad programmers, man up pussy". I like C, I use it a lot, it's one of the first languages I learned and it's been my main "professional" language for more than a decade. Yet I can also see that it has many unnecessary sore points. Having switch not break by default, gets(), array shenanigans, some aliasing rules, the hundreds of completely different meanings for "static", macro hygiene and I could go on... You can say "it's not a big deal and it's not going to change at that point anyway" and sure, I'm not arguing for a revolution, but let's not act that it's an absolutely perfect language and I'm an idiot that doesn't get it for pointing out these issues.

Re:Massacring C Pointers by wruza on Wednesday June 27, 2018 @09:17AM (#17407871)
Sledgehammer defaults to nothing, it just lies around before someone takes it and makes an action. You're basically saying that if a label on the tool misleads you, then you're not in charge and the tool is broken. That doesn't work in engineering, nor is it forgivable to not meet all formal requirements (like reading the documentation thoroughly). You have to look at your tool to find its best fit or at least to find a handle; moreover, labels mean nothing - they are just nicknames for synopsis. Who thinks otherwise should consider javascript or alikes. We live in a world where labels create the entire meaning, but let's not fall into this idiocy in workplaces.

The linux manual for strncpy makes few good notes about its usage and that has a meaning, since it is official and will not change due someone ranting about something again.

Re:Massacring C Pointers by int0x80 on Tuesday June 26, 2018 @02:24PM (#17402906)
Absolutely. strncpy is a very badly designed interface. Is it documented? Yes. Does that make it any good? No.

Principle of least surprise. Idiot proof. Semantics that match common usage. Call it what you like.

Re:Massacring C Pointers by jschwartzi on Tuesday June 26, 2018 @07:37PM (#17404764)
I'm not arguing that it's a completely perfect language. But broken is an incredibly strong word for something that works when used as described in the documentation.

I think the API designer was trying to be parsimonious and not assume too much about what you want to do with the data in your destination buffer. The requirement was to provide buffer overrun protection when the source string is too large, and this function provides that. Beyond that, the requirement that the character array be null-terminated is your decision.

In fact, if you determine that it isn't null-terminated you can do other things besides null terminate it yourself. You might want to provide a helpful error message to consumers of your API rather than truncating their input data silently. Or you may try reallocating your buffer until the string fits. There's actual error handling that you can do with this function. In contrast, automatically null terminating the string makes that more difficult.

The other issues that you have with C seem like preferences. There's nothing wrong with not breaking by default in a switch statement as long as you know that that's what happens.

Re:Massacring C Pointers by ehaliewicz2 on Tuesday June 26, 2018 @03:07PM (#17403222)
That's a poor analogy. It calls itself a string function but isn't. So it's more like a airsoft gun that actually shoots bullets, but you don't know until you decide to shoot yourself in the leg to see what it feels like.
Re:Massacring C Pointers by wruza on Tuesday June 26, 2018 @11:33AM (#17401391)
If you had to name it according to unix traditions, how would you?
Re:Massacring C Pointers by buckminster on Tuesday June 26, 2018 @01:21PM (#17402430)
Maybe fldcpy and fldcat to make clear than a fld (field) is entirely distinct from a str. A better choice if you have a time machine would be to remove these from standard C altogether.