Just make your own string functions from scratch when using C, you'll thank me later.
First, you make two structs: str_buf { capacity, len, data[] } and str_view { len, data* }.
Then write your string handling functions to write into a str_buf* and read from str_views. You have the length and capacity available so memcpy is easy and safe to use.
The str_buf treats capacity as 1 less than it really is such that it can ensure there's always a stupid 0 at the end for compatibility with APIs that expect 0 terminated strings.
There you go, no more security bugs, no more nonsense.
> The str_buf treats capacity as 1 less than it really is such that it can ensure there's always a stupid 0 at the end for compatibility with APIs that expect 0 terminated strings.
Off-by-one errors are a thing.
> Just make your own string functions from scratch when using C, you'll thank me later.
No, if you're going to use C and you need a string type use a well supported string library so that you don't end up reinventing the wheel (probably in a buggy way) and benefit from the battle testing that that code has gone through.
If we're looking at actual strings (as in text) then I'd use 'libunistring'.
First, you make two structs: str_buf { capacity, len, data[] } and str_view { len, data* }.
Then write your string handling functions to write into a str_buf* and read from str_views. You have the length and capacity available so memcpy is easy and safe to use.
The str_buf treats capacity as 1 less than it really is such that it can ensure there's always a stupid 0 at the end for compatibility with APIs that expect 0 terminated strings.
There you go, no more security bugs, no more nonsense.