7 ms·
He is not wrong, is he? If you are using null terminated strings that's the thing you need to fix. I still support this addition. If you are doing methamphetam
by sanxiyn 3y ago
He is not wrong, is he? If you are using null terminated strings that's the thing you need to fix.
I still support this addition. If you are doing methamphetamine with needle sharing you should stop methamphetamine, but distributing clean needles is still an improvement.
- parasti 3y agoWhat a crazy metaphor! You're equating using zero terminated strings in C to doing drugs.
- saagarjha 3y agoI feel like the success rate of getting someone off of null terminated strings is probably lower than most rehabilitation programs.
- IshKebab 3y agoWe can't entirely because of the C ABI but apart from that it's as simple as not using C which is not too difficult. C is not a popular language these days.
- masklinn 3y ago“Apart from that” does a lot of work here: FFI layers generally talk nul-terminated string unless otherwise specified, so do syscalls.
- IshKebab 3y agoYes that's what I said. You can generally wrap those layers so you aren't actually manipulating null terminated strings; just converting to/from them which is not too bad.
- chasil 3y agoWell, you will need to give up SQLite if you really feel this way, and reimplement it in a safe language. It will also be some time before Rust has substantial penetration into Linux; you might need to find a kernel that implements the POSIX interfaces safely. These will not be easy problems to solve.
- saagarjha 3y agoYeah, no…
- torstenvl 3y agoI don't know what you're relying on for the idea that C is not a popular language, but it is extremely popular.
- masklinn 3y agoI mean it’s a wash, on the one hand zero terminated strings have done untold amounts of damage[0] and are impossible to extirpate once they’re in, on the other hand the nazis were methed (and coked later on) up their eyeballs. [0] and not just in C itself, unexpected truncation through FFI is an issue which regularly pops up
- GoblinSlayer 3y agoodbc defines multilingual interface that can accept both null terminated and length bounded strings by using NTS sentinel value for null terminated string length.
- mort96 3y agoWhat's up with people seeing an analogy and going "you can't equate those two things"? Analogies aren't equating things
- rtpg 3y agoAnalogies are great since they talk about how things are the same, and just as terrible because they talk about things that are different. But seriously it’s sometimes hard to slice out what level of similarity is implied. Obvious things are somewhat less obvious to others sometimes
- eru 3y agoWell, the wider problem then is using C.
- ricardo81 3y agoAs a user posting from a Linux machine, I disagree. Though it seems the "don't use C" crowd often delegate the important decisions to somewheres else. I guess the answer is "some people's C is good enough, but not yours"
- tremon 3y agoIf the problem is "you're using nul-terminated strings" as the GP said, then "don't use C" a good step towards fixing that problem, no?
- ricardo81 3y agoPerhaps, but also realistic to accept that you're using code where other people do/have and that the same logic would apply to them.
- jchw 3y agoYou only have to care about it at boundaries though, for the most part. Like, when calling a C API. That's easy to handle. Even C++'s std::string can do that, as the c_str method always returns a null-terminated string. That inherently kills the need for things like strcat.
- lelanthran 3y agoThe return from c_str cannot be used everywhere you would normally use a null terminated string, because the return is const. For example, you couldn't pass it to strtok, or any other function that needs to even temporarily modify the string.
- 3y ago
- woodruffw 3y agoYes, he’s wrong. To apply your metaphor: improvements to the mess that is string handling in C are still an improvement, even if they don’t solve the underlying problem.
- kazinator 3y agoHe's not wrong. The main reason to have these functions is that other implementations have them, and programs are using them, and having to define those functions themselves when ported to glibc. One benefit of defining strlcpy yourself is that you can define it as a macro that expands to an open-coded call to snprintf, and then that is diagnosed by GCC; you may get static warnings about possible truncation. (I suspect GCC might not yet be analyzing strlcpy/strlcat calls, but that could change.) The functions silently discard data in order to achieve memory safety. Historically, that has been viewed as acceptable in C coding culture. There are situations in which that is okay, like truncating some unimportant log message to "only" 1024 characters. Truncating can cause an exploitable security hole; like some syntax is truncated so that its closing brace is missing, and the attacker is able to somehow complete it maliciously. Even when arbitrary limits are acceptable, silently enforcing them in a low-level copying function may not be the best place in the program. If the truncation is caused by some excessively long input, maybe that input should be validated close to where it comes into the program, and rejected. E.g. don't let the user input some 500 character field, pretend you're saving it and then have them find out the next day that only 255 of it got saved. Even if in my program I find it useful to have a truncating copying function, I don't necessarily want it to be silent when truncation occurs. Maybe in that particular program, I want to abort the program with a diagnostic message. I can then pass large texts in the unit and integration tests, to find the places in the program that have inflexible text handling, but are being reached by unchecked large inputs.
- kazinator 3y agoExample: #include <stdio.h> #include <string.h> #define strlcpy(dst, src, size) ((size_t) snprintf(dst, size, "%s", src)) size_t (strlcpy)(char *dst, const char *src, size_t size) { return strlcpy(dst, src, size); } int main(void) { char littlebuf[8]; strlcpy(littlebuf, "Supercalifragilisticexpealidocious", sizeof littlebuf); return 0; } strlcpy.c: In function ‘main’: strlcpy.c:4:63: warning: ‘%s’ directive output truncated writing 34 bytes into a region of size 8 [-Wformat-truncation=] #define strlcpy(dst, src, size) ((size_t) snprintf(dst, size, "%s", src)) ^ strlcpy.c:14:22: strlcpy(littlebuf, "Supercalifragilisticexpealidocious", sizeof littlebuf); ~ strlcpy.c:14:3: note: in expansion of macro ‘strlcpy’ strlcpy(littlebuf, "Supercalifragilisticexpealidocious", sizeof littlebuf); ^~~~~~~ strlcpy.c:4:34: note: ‘snprintf’ output 35 bytes into a destination of size 8 #define strlcpy(dst, src, size) ((size_t) snprintf(dst, size, "%s", src)) ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ strlcpy.c:14:3: note: in expansion of macro ‘strlcpy’ strlcpy(littlebuf, "Supercalifragilisticexpealidocious", sizeof littlebuf); ^~~~~~~ If glibc doesn't do something in the header file such that we get similar diagnostics for its strlcpy, we can make the argument that this is detrimental to the program.