Buffer overflows in C are solely due to bad API design, not inherent to C syntax. First we had naive APIs like gets() which did no bounds checking at all. Then we got checked APIs that let you specify the size of a buffer...
Conversation
which resulted in the rise of off-by-one errors due to the ease of miscalculating the remaining length in a buffer after multiple concatenated uses of the buffer. These still missed the point, bounds checking is about knowing where a buffer ends. Not where it begins.
1
1
The safe strcpy I proposed is immune to buffer overflows. The end of a buffer is invariant across multiple calls, it was always the only relevant piece of data to pass. Not a buffer's remaining length. twitter.com/hyc_symas/stat
Don't blame the language for crappy library designs.
Quote Tweet
Safe strcpy
char *stecpy(char *d, const char *s, const char *e)
{
while (*s && d < e)
*d++ = *s++;
if (d < e)
*d = '\0';
return d;
}
main() {
char buf[64];
char *ptr, *end = buf+sizeof(buf) ;
ptr = stecpy(buf, "hello", end);
ptr = stecpy(ptr, " world", end);
}
Show this thread
1
6
These are the two essential parts to problem solving - recognizing/correctly identifying a problem, and correctly addressing it in a solution. Blaming the C language as a whole just shows poor problem solving skills.
1
1
4
Replying to
Defining proper string and string view types with a pointer + length or pair of pointers was always an option.
It's an option though, not mandatory, and not how most people use C. It addresses spatial safety for strings but not temporal safety which is the much harder problem.
2
It's not quite so simple for arrays and array views since those need to handle multiple types. Multiple dimensions without syntactic sugar isn't that bad.
If you use views rather than copies for efficiency, it makes temporal safety harder so safer C involves defensive copies.
1
Rust doesn't do anything innovative to provide spatial safety. It simply has fully enforced bounds checking. It predates C and wouldn't be that hard to bolt onto C.
It's temporal safety and thread safety where it brought something new to the table via the lifetime/alias checks.


