January 11, 2024 Re: Interpolated strings and SQL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 1/10/24 01:03, Walter Bright wrote: > On 1/9/2024 12:04 AM, Nickolay Bukreyev wrote: >> I’ve just realized DIP1036 has an excellent feature that is not evident right away. Look at the signature of `execi`: >> >> ```d >> auto execi(Args...)(Sqlite db, InterpolationHeader header, Args args, InterpolationFooter footer) { ... } >> ``` >> >> `InterpolationHeader`/`InterpolationFooter` _require_ you to pass an istring. Consider this example: >> >> ```d >> db.execi(i"INSERT INTO items VALUES ($(x))".text); >> ``` >> >> Here, we accidentally added `.text`. It would be an SQL injection… but the compiler rejects it! `typeof(i"...".text)` is `string`, and `execi` cannot be called with `(Sqlite, string)`. > > The compiler will indeed reject it (The error message would be a bit baffling to those who don't know what Interpolation types are), along with any attempt to call execi() with a pre-constructed string. > > The end result is that to do manipulation with istring tuples, the programmer is alternately faced with adding Interpolation elements or filtering them out. Is that really what we want? What we want that DIP1036e mostly provides is: 0. The library can detect whether it is being passed an istring. 1. The library that accepts the istring decides how to process it. 2. The string parts of the istring are known to the library at compile time. 3. The expression parts of the istring can be evaluated only at runtime. 4. The expression parts of the istring can be passed arbitrarily, by ref, lazy, alias, ... (this part in fact works better with DIP1027). 5. The library can access the original expression, e.g. in string form. 6. A templated function that is called with an istring can do all of the above. > Will that impede the use of tuples generally, or just impede the use of istrings? > ... It's just a way to achieve 0.-6. above relatively well with a simple patch to the lexer. I am not sure why it would impede anything except compile time and binary size. > --- > > P.S. most keyboarding bugs result from neglecting to add needed syntax, not typing extra stuff. This is why: > > int* p; > > is initialized to zero, while: > > int* p = void; > > is left uninitialized. The user is unlikely to accidentally type "= void". The user (especially the kind of user that may be prone to accidentally introduce an SQL injection attack) is more likely to accidentally type `.format` or `.text` because that may be a relatively common way to use an istring in their code base. |
January 11, 2024 Re: Interpolated strings and SQL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nickolay Bukreyev | On 1/10/24 16:07, Nickolay Bukreyev wrote:
>>
>
> Yes! It would be brilliant if `alias` could refer to any Expression, not just symbols. If that was the case, we could just pass InterpolationHeader/Footer/etc. to template parameters (as opposed to runtime parameters, where they go now).
I am not a big fan of this option. If we are going to allow passing runtime arguments as template parameters, we might as well just allow passing template parameters as runtime arguments instead. It's much more clear how to make that work.
|
January 11, 2024 Re: Overhead of DIP1036 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 1/10/24 22:21, Walter Bright wrote:
> On 1/10/2024 12:56 PM, Hipreme wrote:
>> - Improving debugging symbols in DMD and for macOS
>> - Improving importC until it actually works
>> - Listen to rikki's complaint about how slow it is to import UTF Tables
>> - Improving support for shared libraries on DMD (like not making it collect an interfaced object)
>> - Solve the problem with `init` property of structs containing memory reference which can be easily be corrupted
>> - Fix the problem when an abstract class implements an interface
>> - Make a D compiler daemon
>> - Help in the project of DMD as a library focused on helping WebFreak in code-d and serve-d
>> - Implement DMD support for Apple Silicon
>> - Revive newCTFE engine
>> - Implement ctfe caching
>
> I regularly work on many of those problems. For example, without looking it up, I think I've fixed maybe 20 ImportC issues in the last month. I've also done a number of recent PRs aimed at making D more tractable as a library. So has Razvan.
Thanks a lot for the incredible amount of work you have invested into D over the years!
|
January 11, 2024 Re: Interpolated strings and SQL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 1/11/24 21:13, Timon Gehr wrote:
>
>
> P.S. most keyboarding bugs result from neglecting to add needed syntax, not typing extra stuff.
if (condition);
{
...
}
I think it's due to muscle memory and it does happen quite a bit.
|
January 11, 2024 Re: Interpolated strings and SQL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 1/10/24 00:21, Walter Bright wrote: > ... The other points I think have been adequately addressed already. >> You are right, it doesn’t. Timon’s point (expressed as “This does not work”) is that DIP1036 is able to do validation at compile time while DIP1027 is only able to do it at runtime, when this function actually gets invoked. > > The only validation it does is check for nested string interpolations. That is not true in the least. It validates conclusively that no SQL injection attack is going on. This is the main feature of the example! |
January 11, 2024 Re: enum Format | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 1/11/2024 11:50 AM, Timon Gehr wrote:
> On 1/11/24 03:21, Walter Bright wrote:
>> As for it being a required feature of string interpolation to do this processing at compile time, that's a nice feature, not a must have.
>
> As far as I am concerned it is a must-have. For example, this is what prevents the SQL injection attack, it's a safety guarantee.
Why does compile time make it a guarantee and runtime not?
We do array bounds checking at runtime.
|
January 11, 2024 Re: enum Format | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 1/11/2024 11:45 AM, Timon Gehr wrote:
> My point was with DIP1036e it either works or does not compile, not that you called the wrong function.
What's missing is why is a runtime check not good enough? The D compiler emits more than one safety check at runtime. For example, array bounds checking, and switch statement default checks.
|
January 11, 2024 Re: Overhead of DIP1036 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 1/11/2024 12:20 PM, Timon Gehr wrote:
> Thanks a lot for the incredible amount of work you have invested into D over the years!
It is indeed my pleasure, especially the privilege of working with you guys!
|
January 12, 2024 Re: enum Format | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 12/01/2024 6:28 PM, Walter Bright wrote: > On 1/11/2024 11:50 AM, Timon Gehr wrote: >> On 1/11/24 03:21, Walter Bright wrote: >>> As for it being a required feature of string interpolation to do this processing at compile time, that's a nice feature, not a must have. >> >> As far as I am concerned it is a must-have. For example, this is what prevents the SQL injection attack, it's a safety guarantee. > > Why does compile time make it a guarantee and runtime not? > > We do array bounds checking at runtime. Where possible we absolutely should not be. Making things crash at runtime, because the compiler did not apply the knowledge it has is just ridiculous. Imagine going to ``http://google.com/itsacrash`` and crashing Google. Or pressing a button too fast on an airplane and suddenly the fuel pumps turn off and then refuse to turn back on. Instead of the compiler catching clearly bad logic that it has a full understanding of, you're disrupting service and making people lose money. This is not a good thing. |
January 11, 2024 Re: Compile Time vs Run Time | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi | On 1/9/2024 3:49 PM, Paolo Invernizzi wrote: > You are underestimating what can be gained as value in catching SQL problems at compile time instead of runtime. And, believe me, it's not a matter of mocking the DB and relying on unittest and coverage. Please expand on that. This is a very important topic. I want to know all the relevant facts. > CTFE capability is needed. I concur that compile time errors are better than runtime errors. But in this case, there's a continuing cost to have them, cost to other far more common use cases for istrings. The cost is in terms of complexity, about needing to filter out all the extra marker templates, about reducing its utility as a tuple generator with the unexpected extra elements, larger object files, much longer mangled names, and so on. Want to know the source of my unease about it? Simple things should be simple. This isn't. The extra complexity is always there, even for the simple cases, and the simple cases are far and away the most common use cases. Frankly, it reminds me of C++ template expressions, which caught the C++ world by storm for about 2 years, before it faded away into oblivion and nobody talks about them anymore. Fortunately for C++, template expressions could be ignored, as they were not a core language feature. But DIP1036 is a core language feature, a feature we would be stuck with forever. And I'll be the one who gets the heat for it. The compile-time vs runtime issue is the only thing left standing where the advantage goes to DIP1036. So it needs a very compelling case. P.S. You can do template expressions in D, too! |
Copyright © 1999-2021 by the D Language Foundation