I'm starting this thread, first, as a shamless plug to a brand new pull I just did, which (amongst others) allows "put" to transcode on the fly any string/char of any length, to any string/char of any length.

This fixes issues mostly in std.format, and also allows things like formattedWrite to work with pure delegates (it didn't before), as well as output directly in wstring or dstring format (awesome for writing to a UTF-16 file, for example).

--------

The real reason I'm starting this thread is I believe the current way "put" leads to a *MASSIVE*, *HORRIFYING* issue. I dare not say it: Escaping references to local stack variables (!!!).

Basically, if R accepts an "E[]", than put will accept a single E element as input, and convert it to an "E[]" on the fly, using "put(r, (&e)[0 .. 1]);". I'm sure you can see the problem. It allows things such as:

//----
void main()
{
    Appender!(int[][]) app; //A type that accumulates slices
    put(app, 1);
    put(app, 2);
    put(app, 3);
    writeln(app.data); //prints: [[3], [3], [3]]
}
//----
Oops!

I'd like to make a proposition: "put" needs to be changed to *not* accept putting an E into something that accepts E[]. There is simply *no way* to do this safely, and without allocating (both of which, IMO, are non-negotiable).

For objects that define put/opCall, then it is not very complicated to have two different signatures for "put(E[])"/"opCall(E[])" *and* "put(E)"/"opCall(E)". This makes it explicit what is and isn't accepted.

Lucky enough, the problem never existed with input ranges: "int[][]" never accepted "int", so there is no problem there.

The last thing remaining are "sinks" (delegates and functions). As a convenience, and *only* for characters sinks, because we *trust* them to make local copies of elements, we can allow things like:
put((const(char)[]){}, 'a');// OK
put((const(char)[]){}, '本');// OK
put((const(char)[]){}, "hello"d);// OK
put((const(wchar)[]){}, "hello"c);// OK

This, I think, is what is safest, but still leaves a little open door, exceptionally, for easy formatting.

--------

So, the idea is now to yay or nay my change proposal, and/or discuss my pull:
https://github.com/D-Programming-Language/phobos/pull/1534

Reply via email to