5 ms·
> While string truncation has its own issues, it is often a fairly reasonable fallback. Seemingly swimming against the tide here; a strcpy() that _automaticall
by zbuf 5y ago
> While string truncation has its own issues, it is often a fairly reasonable fallback.
Seemingly swimming against the tide here; a strcpy() that _automatically_ truncates strings is a worse, and huge hidden risk.
Yes, buffer overflows from user data are very, very bad.
But a buffer overflow has a clear fingerprint as leaning on undefined behaviour; tools exist to detect these (eg. valgrind), and the fix is well understood.
Defining strcpy to include truncation is the wrong choice, as it's plain dangerous in most cases. It reclassifies the bug as valid program behaviour, where it's riskier and its fingerprint is harder to detect.
For example, a function which looks up credentials for a login name limited to 16 characters. During lookup, a buffer truncates and by default the code is now doing lookups against the wrong login name.
The better solution is a strcpy() which accepts a length and is _expressly not defined_ for cases where the output buffer would overflow; ie. asserts or aborts (which now has scope to be detected at compile time for some cases)
It's now clear where bug is, and a developer must preempt overflow for cases where it's possible and handle it.
Perhaps folks have different experiences, but mine is that copying a string and _wanting_ to truncate it is so incredibly rare and is the cases that should be explicit, not implicit.
- saagarjha 5y agoFailing perceptibly composes better than failing loudly. It's easy to go one way: char *strxxxcpy(char *restrict dst, const char *restrict src, size_t len) { char *result = strxcpy(dst, src, len); assert(result); return result; } but going in reverse is difficult.
- zbuf 5y agoBut that misses my point; the bug is that as a developer it's too easy to not write the correct check -- like exactly this one. The library function presented to most developers (especially a novice one) should reflect the most common case, not the more-easy-to-compose case.