Live data from Hacker News

No strcpy either

daniel.haxx.se

61–70 of 151 posts

Re: No strcpy either

#61
post #18

I've always wondered at the motivatons of the various string routines in C - every one of them seems to have some huge caveat which makes them useless. After years I now think it's essential to have a library which records at least how much memory is allocated to a string along with the pointer. Something like this: https://github.com/msteinert/bstring

Yes, not having a length along with the string was a mistake. It dates from an era where every byte was precious and the thought of having two bytes instead of one for length was a significant loss.

I have long wondered how terrible it would have been to have some sort of "varint" at the beginning instead of a hard-coded number of bytes, but I don't have enough experience with that generation to have a good feel for it.

Re: No strcpy either

#62
post #53

It's worth noting that strcpy() isn't just bad from a security perspective, on any CPU that's not completely ancient it's bad from a performance perspective as well. Take the best case scenario, copying a string where the precise length is unknown but we know it will always fit in, say, 64 bytes. In earlier days, I would always have used strcpy() for this task, avoiding the "wasteful" extra copies memcpy() would make…

We should just move away from null-terminated strings, where we can, as fast as we can.

Re: No strcpy either

#63
post #4

The AI chatbot vulnerability reports part sure is sad to read. Why is this even a thing and isn't opt-in? I dread the idea of starting to get notifications from them in my own projects.

Making a strcpy honeypot doesn’t sound like a bad idea… void nobody_calls_me(const char *stuff) { char *a, *b; const size_t c = 1024; a = calloc(c); if (!a) return; b = malloc(c); if (!b) { free(a); return; } strncpy(a, stuff, c - 1); strcpy(b, a); strcpy(a, b); free(a); free(b); } Some clever obfuscation would make this even more effective.

That got those Core SDI abo vibes.

Flashback of writing exploits for these back in high school.

Re: No strcpy either

#64
post #62
post #53

It's worth noting that strcpy() isn't just bad from a security perspective, on any CPU that's not completely ancient it's bad from a performance perspective as well. Take the best case scenario, copying a string where the precise length is unknown but we know it will always fit in, say, 64 bytes. In earlier days, I would always have used strcpy() for this task, avoiding the "wasteful" extra copies memcpy() would make…

We should just move away from null-terminated strings, where we can, as fast as we can.

Yes

And maybe even have a (arch dependent) string buffer zone where the actual memory length is a multiple of 4 or even 8

Re: No strcpy either

#65
post #59
post #55

Earlier quoted context omitted.

Yet software developed in C, with all of the foibles of its string routines, has been sold and running for years with trillions of USD is total sales. A library that records how much memory is allocated to a string along with the pointer isn't a necessity. Most people who write in C professionally are completely used to it although the footgun is (and all of the others are) always there lurking. You'd generally just…

> Yet software developed in C, with all of the foibles of its string routines, has been sold and running for years with trillions of USD is total sales. This doesn't seem very relevant. The same can be said of countless other bad APIs: see years of bad PHP, tons of memory safety bugs in C, and things that have surely led to significant sums of money lost. > It's also very easy to get this wrong, I almost wrote `hostn…

Sure, the post I was replying to made it sound like it's a surprise that anything written in C could ever have been a success.

Not many people starting a new project (commercial or otherwise) are likely to start with C, for very good reason. I'd have to have a very compelling reason to do so, as you say there are plenty of more suitable alternatives. Years ago many of the third party libraries available only had C style ABIs and calling these from other languages was clumsy and convoluted (and would often require implementing cstring style strings in another language).

> Why would you do this separately every single time, then?

It was just an illustration or what people used to do. The "set the trailing NUL byte after a strncpy() call" just became a thing lots of people did and lots of people looked for in code reviews - I've even seen automated checks. It was in a similar bucket to "stuff is allocated, let me make sure it is freed in every code path so there aren't any memory leaks", etc.

Many others would have written their own function like `curlx_strcopy()` in the original article, it's not a novel concept to write your own function to implement a better version of an API.

Re: No strcpy either

#66
post #57

"strncpy() is a weird function with a crappy API." Well if you bother looking up that it's originally created for non null-terminated strings, then it kinda makes sense. The real problem begun when static analyzers started to recommend using it instead of strcpy (the real alternative used to be snprintf, now strlcpy).

Your comment makes no sense. If it was designed for non-null terminated strings, why would it specifically pad after a null terminator?

I looked up the actual reason for its inception:

---

    Rationale for the ANSI C Programming Language", Silicon Press 1990.

    4.11.2.4 The strncpy function
    strncpy was initially introduced into the C library to deal with fixed-length name fields in structures such as directory entries. Such fields are not used in the same way as strings: the trailing null is unnecessary for a maximum-length field, and setting trailing bytes for shorter names to null assures efficient field-wise comparisons. strncpy is not by origin a "bounded strcpy," and the Committee has preferred to recognize existing practice rather than alter the function to better suit it to such use.

Re: No strcpy either

#67
post #28

Earlier quoted context omitted.

strncpy is fairly easy, that's a special-purpose function for copying a C string into a fixed-width string, like typically used in old C applications for on-disk formats. E.g. you might have a char username[20] field which can contain up to 20 characters, with unused characters filled with NULs. That's what strncpy is for. The destination argument should always be a fixed-size char array. A couple years ago we got a…

strncpy doesn’t handle overlapping buffers (undefined behavior). Better to use strncpy_s (if you can) as it is safer overall. See: https://en.cppreference.com/w/c/string/byte/strncpy.html . As an aside, this is part of the reason why there are so many C successor languages: you can end up with undefined behavior if you don’t always carefully read the docs.

> strncpy doesn’t handle overlapping buffers (undefined behavior).

It would make little sense for strncpy to handle this case, since, as I pointed out above, it converts between different kinds of strings.

Re: No strcpy either

#68
post #55
post #18

I've always wondered at the motivatons of the various string routines in C - every one of them seems to have some huge caveat which makes them useless. After years I now think it's essential to have a library which records at least how much memory is allocated to a string along with the pointer. Something like this: https://github.com/msteinert/bstring

Yet software developed in C, with all of the foibles of its string routines, has been sold and running for years with trillions of USD is total sales. A library that records how much memory is allocated to a string along with the pointer isn't a necessity. Most people who write in C professionally are completely used to it although the footgun is (and all of the others are) always there lurking. You'd generally just…

I learned C in about 1989/1990 and have used it a lot since then. I have worked on a fair amount of rotten commercial C code, sold at a high price, in which every millimeter of extra functionality was bought with sweat and blood. I once spent a month finding a memory corruption issue that happened every 2 weeks with a completely different stack trace which, in the end, required a 1-line fix.

The effort was usually out of proportion with the achievement.

I crashed my own computer a lot before I got Linux. Do you remember far pointers? :-( In those days millions of dollars were made by operating systems without memory protection that couldn't address more than 640k of memory. One accepted that programs sometimes crashed the whole computer - about once a week on average.

Despite considering myself an acceptable programmer I still make mistakes in C quite easily and I use valgrind or the sanitizers quite heavily to save myself from them. I think the proliferation of other languages is the result of all this.

In spite of this I find C elegant and I think 90% of my errors are in string handling so therefore if it had a decent string handling library it would be enormously better. I don't really think pure ASCIIZ strings are so marvelous or so fast that we have to accept their bullshit.

Re: No strcpy either

#69

> Enforce checks close to code This makes a lot of sense but one time I find this gets messy is when there’s times I need to do checks earlier in a dataset’s lifetime. I don’t want to pay to check multiple times, but I don’t want to push the check up and it gets lost in a future refactor. I’m imagining a metadata for compile time that basically says, “to act on this data it must have been first checked. I don’t care…

I'd use different types for those. Like Java's String vs. CharSequence.

Re: No strcpy either

#70
post #18

I've always wondered at the motivatons of the various string routines in C - every one of them seems to have some huge caveat which makes them useless. After years I now think it's essential to have a library which records at least how much memory is allocated to a string along with the pointer. Something like this: https://github.com/msteinert/bstring

> I've always wondered at the motivatons of the various string routines in C

This idiom:

    char hostname[20];
    ...
    strncpy( hostname, input, 20 );
    hostname[19]=0;
exists because strncpy was invented for copying file names that got stored in 14-byte arrays, zero terminated only if space permitted (https://stackoverflow.com/a/1454071)
Post reply on HN