Make printf safe

Walter Bright newshound2 at digitalmars.com
Tue Jul 16 01:22:14 UTC 2024


On 7/15/2024 12:56 PM, Paul Backus wrote:
>> How is it not safe?
> 
> C23, section 7.23.6.1 ("The fprintf function"), paragraph 5:
> 
>> As noted previously, a field width, or precision, or both, may be indicated
>> by an asterisk. In this case, an int argument supplies the field width or
>> precision. [...] A negative precision argument is taken as if the precision
>> were omitted.
> 
> So, if the length overflows a 32-bit int, it will be ignored, and printf will 
> read until it finds a zero byte.

Huh, I missed that little gem!

But there's a simple solution:

```
printf("%.*s\n", cast(int)s.length & 0x7FFF_FFFF, s.ptr);
```

Hence, it will always be a positive integer.

That means one can print a maximum of 2 billion characters via printf. Like 
640Kb, that ought to be enough for anyone!

While failing to print the entirety of such a (suspiciously) long string, it 
would not be a memory safety issue.


> I suppose we could have the compiler insert a bounds check, in addition to all 
> of the other rewrites, but at this point, it feels like we're not really calling 
> printf at all; we're calling some other formatted-output function that's stolen 
> printf's identity.

Wrapping APIs with a better interface is what we do all the time :-/


More information about the dip.ideas mailing list