[OT] C# can do all the interpolated strings now

Steven Schveighoffer schveiguy at gmail.com
Thu Dec 9 15:07:01 UTC 2021


On 12/9/21 9:33 AM, kdevel wrote:
> On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven Schveighoffer wrote:
>> On 12/8/21 4:31 PM, kdevel wrote:
> [...]
> 
>>> How is the proper separation of code (query) and data achieved in 
>>> this case?
>>
>> Because the `sqlExec` function figures it out based on the 
>> interpolation header. It can tell which parts were literal strings, 
>> and which parts were interpolation parameters.
> 
> So the string interpolation is used to emulate something like embedded 
> SQL (ESQL) with the exception that the (SQL) code is quoted. ESQL looks 
> like this [1]:
> 
> ```
>     EXEC SQL INSERT INTO tablename VALUES (:variablename);
> ```
> 
> This is clearly favorable over embedded question marks plus argument lists.

Yes, this is the biggest point of the DIPs that have been introduced so 
far -- put the parameters in context.

> 
>> The interpolation parameters are replaced with "?", and then the 
>> parameters are passed as data (to avoid SQL injection as expected).
> 
> I missed that part.

It might be implied and not specifically spelled out (I don't know, I 
read the DIP a long time ago).

> 
> [...]
> 
>> e.g. (from a real line of code in my codebase):
>>
>> ```d
>> conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = 
>> ?", loc_latitude, loc_longitude, id);
>>
>> // compare to:
>> conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, loc_lon = 
>> $loc_longitude WHERE id = $id");
>> ```
> 
> Final questions: What happens if the "i" in front of the string is 
> accidentally lost? Compile-time oder runtime error?

It depends. If `conn.exec` accepts a standard `string`, then it's a 
runtime error -- without the i, the string is just a string, which 
contains the literal data with `$loc_latitude`, etc. which the SQL 
server doesn't understand. This is similar to what happens when you do 
(as I often do): `writeln("%s: %s", name, value);`

If `conn.exec` only accepts interpolated literals, then it's a compile 
time error.

> How does the compiler/runtime know which type of interpolation to 
> choose? I mean if you have
> 
> ```
>     conn.exec (i"UPDATE organization SET loc_lat = $loc_latitude...
>     html.output (i"<input value=\"$value\" ...
> ```
> 
> how and where is decided to use the SQL interpolation in the first and 
> the HTML escaping in the second line?

That is the beauty of this proposal! The parameters are simply passed 
as-is into the function. If the function accepts them properly, it gets 
to decide how to handle it.

html.output can do whatever it wants differently than conn.exec.

> 
> What is the return type of the interpolation?

There isn't one. The interpolation is not a function, it's a literal 
that expands into a parameter list.

> 
> PS: The following code snippet is from the YAIDIP document:
> 
> ```
>     executeShell("wget " ~ url ~ " -O" ~ file ~ ".frag && mv " ~ file ~ 
> ".frag " ~ file);
> ```
> 
> That should not have been written in the first place. This code is prone 
> to shell injection and the only shell-specific functionality is that of 
> the "&&". Long story short: I would have written it that way:
> 
> ```
>     execute(["wget", url, "-O", file ~ ".frag"]).status == 0
>     &&
>     execute(["mv", file ~ ".frag ", file]);
> ```
> 

Yeah, it might not explicitly state that the original code is subject to 
injection, but the interpolated version has the *potential* to avoid it, 
whereas the original snippet has no chance.

-Steve


More information about the Digitalmars-d mailing list