The state of string interpolation
Steven Schveighoffer
schveiguy at gmail.com
Thu Dec 6 19:27:05 UTC 2018
On 12/6/18 2:12 PM, Paul Backus wrote:
> Marler's original proposal is simple, orthogonal, and elegant. It makes
> use of existing D features in natural ways, and is both easy to
> understand, and easy to use in simple cases without *needing* to
> understand it. I think adding additional machinery like
> FromInterpolation on top of it would be a mistake. If users want to opt
> in to that extra complexity, it can always be made available as a library.
I agree with this. But the points brought up are good ones.
>
> On Thursday, 6 December 2018 at 18:28:09 UTC, Neia Neutuladh wrote:
>> I was thinking about protecting against errors produced when you have
>> to use an even/odd rule to figure out what's part of the literal and
>> what's part of the interpolation:
>>
>> auto c = ");drop table foo;--";
>> // whoops, forgot a comma
>> db.exec("SELECT * FROM foo WHERE id IN ($a,$b$c)");
>> ->
>> db.prepare("SELECT * FROM foo WHERE id IN(?, ?);drop table foo;--?")
>> .inject(a, b, ")");
>>
>> With FromInterpolation, you'd be able to reliably come up with the
>> correct SQL: "SELECT * FROM foo WHERE id IN (?, ??)". Which is invalid
>> and would be rejected.
>
> The actual solution here is to use the type system to distinguish
> between trusted and untrusted strings. E.g.,
>
> UnsafeString c = getUserInput(); // e.g., "); drop table foo;--"
> db.exec("SELECT * FROM foo WHERE id IN ($a,$b$c)");
>
> ....and `db.exec` knows to escape its arguments iff they're UnsafeStrings.
The more I think about it, the better it is to use the original
proposal, and just pass the parameters at compile time in order to make
it work. The non-string portions will be aliases to the expressions or
variables, making them easily distinguishable from the string portions.
So instead of my original db.exec(...), you'd do db.exec!(...), exactly
the same as before, just it's passed at compile time vs. runtime. The
runtime possibility is there too, but you wouldn't use it in a database
setting.
This can be used to forward to whatever you want. If you want to change
the parameters to FromInterpolation("foo", foo), it will be possible.
This is very D-ish, too, where we supply the compile-time mechanisms,
and you come up with the cool way to deal with them.
-Steve
More information about the Digitalmars-d
mailing list