Невозможно использовать FormattableString

Читая эту интересную статью о предотвращении SQL-инъекций в EF Core, я обнаружил, что теперь интерполированная строка может привести к FormattableString,

Запуск этого тестового кода в.NET Core 2.2:

public static void Main()
{
    var filter = "Mark'; DROP TABLE tbl; --";

    Console.WriteLine(FromSql("SELECT * FROM tbl WHERE fld = '" + filter + "'"));
    Console.WriteLine(FromSql($"SELECT * FROM tbl WHERE fld = {filter}"));
    Console.WriteLine(FromSql(FormattableStringFactory.Create(
                                  "SELECT * FROM tbl WHERE fld = {0}", filter)));
}

private static string FromSql(string sql) => sql;

private static string FromSql(FormattableString sql)
{   
    var formatArgs = sql.GetArguments();

    for (var paramIndex = 0; paramIndex < sql.ArgumentCount; ++paramIndex)
        formatArgs[paramIndex] = "@p" + paramIndex;

    return sql.ToString();
}

не дает то, что я ожидал:

SELECT * FROM tbl WHERE fld = 'Mark'; DROP TABLE tbl; --'
SELECT * FROM tbl WHERE fld = Mark'; DROP TABLE tbl; --
SELECT * FROM tbl WHERE fld = @p0

Второй отпечаток должен выводиться как последний.

Попробуйте это скрипка.

Что мне не хватает?

1 ответ

Решение

Ваш второй звонок Console.WriteLine(FromSql($"SELECT * FROM tbl WHERE fld = {filter}")); похоже собирается в FromSql(string sql) перегрузка вместо FromSql(FormattableString sql),

Просто удалите FromSql(string sql) метод (и первый вызов к нему),
и все пойдет как положено; см. модифицированную скрипку.


Компилятор вроде переводитvar q = $"SELECT * FROM tbl WHERE fld = {filter}"; к string,

 String q = $"SELECT * FROM tbl WHERE fld = {filter}";`  

Из-за string наберите "А String.Format состоялся
Из документации:

Если интерполированная строка имеет строку типа, она обычно преобразуется в вызов метода String.Format.


Принимая во внимание, явно указав FormattableString как в

FormattableString q = $"SELECT * FROM tbl WHERE fld = {filter}";  

FormattableStringFactory.Create используется.
Из документации:

Если интерполированная строка имеет тип IFormattable или FormattableString, компилятор генерирует вызов метода FormattableStringFactory.Create.

Другие вопросы по тегам