Correct ≠ safe

I wrote, too optimistically:

It's easy to write correct string operations, even in C, even for null-terminated strings in fixed-size buffers — and security-conscious C programmers often do.

Barry Kelly objected:

I don't agree that it is easy [...] to write correct code in C for manipulating null-terminated strings in fixed sized buffers, for a simple reason: if you can't let the fixed length follow the string, either via static typing or dynamically, then normal procedural abstraction will tend to hide the length and lead to errors later.

I didn't find that very convincing until a few weeks ago, when I spent a late night tracking down a mysterious buffer overflow: I had used a “safe” string operation with the wrong buffer size.


  1. I find it so hard to believe the amount of bugs and pain we endure for the sake of a few cycles.

  2. Optimization has an immediate payoff in feelings of superiority and real-programmer-hood; safety generally has no emotional reward. That may explain a lot.

    But at least in this case, it's less for the sake of cycles than from programmer conservatism. std::string is better for most things, but convincing people to use it is hard, especially when it doesn't come with sprintf or amortized-linear-time appending. (I ran into that last one recently.)

  3. Consider the following: gopher://*d

    This program does not use string buffers for anything other than configuration data (which is known to be safe); most things are just copied and parsed directly. This shows that in some cases you do not need to make buffers for some things if you just read one character.


It's OK to comment on old posts.