5 ms·
Vulnerabilities like buffer overflow do not happen in languages with a string type. Humans are responsible if something bad happens, but without a safety net, t
by junke 10y ago
Vulnerabilities like buffer overflow do not happen in languages with a string type. Humans are responsible if something bad happens, but without a safety net, the outcome is worse.
- sidlls 10y agoYour first statement is pretty false, even in Rust (for example). Unless you mean something else by "buffer overflow" than I'm accustomed to.
- junke 10y agoYou are right, "do not happen" sounds too much like "will never happen". See also Wikipedia's entry about that example[0]. My point is that if the programmer can't prove accesses are always within appropriate bounds, there should be a runtime check. That is simple. This is not "slow" (and even in the case it you need it fast and are ok to randomly crash, avoiding checks should be explicit). And some languages do it by default and make it really hard to mess with memory. [0] https://en.wikipedia.org/wiki/Buffer_overflow#Choice_of_programming_language https://en.wikipedia.org/wiki/Buffer_overflow#Choice_of_prog...
- sidlls 10y agoWell, yes, I agree in general bounds should be checked at runtime when it isn't possible to statically verify access at compile time. I'm not sure how default access in C or C++ isn't explicitly avoiding checks. By definition "a[b]" is an unchecked dereference. It doesn't get more explicit than "by definition." Of course if by "explicit" you mean "syntax exists that demarcates unchecked access" then C and C++ will never satisfy. I'd argue that's a contrived and artificially narrow use of "explicit" meant, er, explicitly to exclude C and C++ from being acceptable by definition and therefore not terribly fair.
- junke 10y agoI mean something like Ada's pragmas: https://en.wikibooks.org/wiki/Ada_Programming/Pragmas/Suppress https://en.wikibooks.org/wiki/Ada_Programming/Pragmas/Suppre...
- sidlls 10y agoYes (Rust's "unsafe" blocks serve the same purpose), and my point is you're narrowing the definition of "explicit" to exclude C or C++ by definition. And that isn't exactly a fair, in my view.
- junke 10y agoThere is no doubt that C, by definition, opts out from performing bound checkings. But if bounds were always checked by default (implicitly), then you would have to opt-out explicitly, which is a safer approach, because all else being equal, in case of a programming mistake, the code ends up not being vulnerable to that specific kind of attack.
- ArkyBeagle 10y agoC has a perfectly useable (null-terminated) string type, and there is no good reason to ever have a buffer overrun in C. I understand that this is... obscure for some reason and I'm not saying it never happens, but let's be realistic....
- Retra 10y agoC has a char* type, which we call a string, but it is also the type of a pointer to a single char, which is not a string at all, and also something perfectly usable. "Ends with nul" is barely a part of C, it's more like a programmer's agreement. The language doesn't enforce it, require it, or check it. All it does is insert nul characters in literals, which is hardly enough to make a string type. Thus if you have a to_upper(char*) function, you don't know what it takes or does without looking it up. Does it uppercase a single character or a whole string? How do you even tell what you were passed without potentially reading past the end of a buffer? If I happen to have a pointer-to-char and pass it to a to_upper function that operates on strings, it will just write on invalid memory, because C can't distinguish between the two.
- ArkyBeagle 10y agoThis is all true. So don't do that.
- Retra 10y agoDon't worry about me, I never make any mistakes. I'm a true C programmer: I believe that "implement a good string type" is an unsolved problem and that the last 50 years never happened.
- spc476 10y agoFrom the signature, I would say it expects a NUL-terminated sequence of characters (a C-string) and it would modify it in-place to upper case each character. C already has a standard C function: extern int toupper(int); (via #include <ctypes.h>) that will upper case a single character. If, on the other hand, I saw: extern char *to_upper(const char *); I would expect that to_upper() returns a new string (freeable via a call to free()) that is the upper case version of the given string. > If I happen to have a pointer-to-char and pass it to a to_upper function that operates on strings, it will just write on invalid memory, because C can't distinguish between the two. Um ... how do you "happen" to have a pointer-to-char? And unknowingly call to_upper()? I'm lost as to how this can happen ...