Comment by AstralStorm
2 years ago
You may not know the function is doing C string manipulation, since const correctness in APIs is not a 100% thing.
2 years ago
You may not know the function is doing C string manipulation, since const correctness in APIs is not a 100% thing.
If it's just incidental mutation that is a concern, rather than intentionally mutating C strings, no problem: it is common-place to defensively clone strings and other memory when passing them to untrusted interfaces. In fact, if this is your fear, you have literally no alternative but to do so, even when programming directly in C.
Then again, if there's no contract for who owns or mutates a given piece of memory, there's no safe way to use said API from any language or environment and you should probably stop using it. Failing that, you'd just have to check the source code and find out what it actually does and hope that it does not change later.
(Of course, this has no bearing on whether or not you should use C strings or C string manipulation: You shouldn't, even if you're touching unsafe APIs. It's extremely error prone at best, and also pretty inefficient in a lot of cases.)
@jchw I don't see anything you write as disagreeable. But clearly you have a strong handle on what needs taken care of.
Turtles all the way down isn't it? At some point, someone has to take responsibility.
Let me reframe this. What we're saying to do is stop using C string manipulation such as strcat, strcpy, etc. Particularly, I'm saying simply don't use C-style null terminated strings until you actually go to call a C ABI interface where it is necessary.
The argument against this is that you might call something that already internally does this, to your inputs directly, without making a copy. Yes, sure, that IS true, but what this betrays is the fact that you have to deal with that regardless of whether or not you add additional error-prone C string manipulation code on top of having to worry about memory ownership, mutation, etc. when passing blobs of memory to "untrusted" APIs.
It's not about passing the buck. Passing a blob of memory to an API that might do horrible things not defined by an API contract is not safe if you do strcat to construct the string or you clone it out of an std::string or you marshal it from Go or Rust. All this is about, is simply not creating a bigger mess than you already have.
Okay fine, but what if someone hates C++ and Rust and Go and Zig? No problem. There are a slew of options for C that can all handle safer, less error-prone string manipulation, including interoperability with null-terminated C strings. Like this one used in Redis:
https://github.com/antirez/sds
And on top of everything else, it's quite ergonomic, so it seems silly to not consider it.
This entire line of thinking deeply reminds me of Technology Connection's video The LED Traffic Light and the Danger of "But Sometimes!".
https://youtube.com/watch?v=GiYO1TObNz8
I think hypothetically you can construct some scenarios where not using C strings for string manipulation requires more care, but justifying error prone C string manipulation with "well, I might call something that might do something unreasonable" as if that isn't still your problem regardless of how you get there makes zero sense to me.
And besides, these hypothetical incorrect APIs would crash horrifically on the DS9K anyways.