[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