Make printf safe
Paul Backus
snarwin at gmail.com
Mon Jul 15 19:56:29 UTC 2024
On Monday, 15 July 2024 at 18:36:07 UTC, Walter Bright wrote:
> On 7/14/2024 7:06 AM, Timon Gehr wrote:
>> On 7/13/24 22:39, Walter Bright wrote:
>>> I propose that the compiler rewrite:
>>>
>>> ```
>>> char[] name;
>>> printf("name = %s\n", name);
>>> ```
>>> into:
>>> ```
>>> printf("name = %.*s\n", cast(int)name.length, name.ptr);
>>> ```
>>> (and mark any other use of %.*s as unsafe)
>>
>> This part is actually not memory safe.
>
> 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.
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.
More information about the dip.ideas
mailing list