On Saturday, 13 July 2024 at 20:39:32 UTC, Walter Bright wrote:
>The idea is printf is already largely safe:
[...]
@safe
functions cannot perform pointer arithmetic, but printf
does because it indexes a char*
(its first parameter).
July 15 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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. |
July 15 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard (Rikki) Andrew Cattermole | On 7/15/2024 11:26 AM, Richard (Rikki) Andrew Cattermole wrote:
>> What is IES?
>
> https://dlang.org/spec/istring.html
Thank you.
|
July 15 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | 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 :-/ |
July 16 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Tuesday, 16 July 2024 at 01:22:14 UTC, Walter Bright wrote:
>> 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 :-/
Of course. What I find objectionable in this case is that (a) the better interface is implemented using a bunch of compiler-internal rewrites, rather than normal D code; and (b) it shadows the existing C printf function rather than existing alongside it.
If we need a safer printf for DMD that doesn't carry all the bloat and baggage of Phobos's writef, then by all means, let's write one. But let's write it in D and put it in a normal D module, instead of sneaking around and redefining printf behind our users' backs.
|
July 16 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | Followups: https://www.digitalmars.com/d/archives/digitalmars/dip/development/First_Draft_Making_printf_safe_266.html |
July 17 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Saturday, 13 July 2024 at 20:39:32 UTC, Walter Bright wrote: >The idea is printf is already largely safe:
|
July 17 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to IchorDev | On Wednesday, 17 July 2024 at 08:58:56 UTC, IchorDev wrote: >On Saturday, 13 July 2024 at 20:39:32 UTC, Walter Bright wrote: >The idea is printf is already largely safe:
The idea is to make certain calls of
See https://forum.dlang.org/post/v775k1$1tmj$1@digitalmars.com. |
July 17 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 17 July 2024 at 09:20:23 UTC, Nick Treleaven wrote: >On Wednesday, 17 July 2024 at 08:58:56 UTC, IchorDev wrote: >On Saturday, 13 July 2024 at 20:39:32 UTC, Walter Bright wrote: >The idea is printf is already largely safe:
The idea is to make certain calls of
See https://forum.dlang.org/post/v775k1$1tmj$1@digitalmars.com. I fail to see why there can’t be a |
July 17 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to IchorDev | Please continue this here: https://www.digitalmars.com/d/archives/digitalmars/dip/development/First_Draft_Making_printf_safe_266.html |
July 17 Re: Make printf safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 17 July 2024 at 09:20:23 UTC, Nick Treleaven wrote: >The idea is to make certain calls of
See https://forum.dlang.org/post/v775k1$1tmj$1@digitalmars.com. And the function will still perform pointer arithmetic. |