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):
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