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