diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnectionInternal.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnectionInternal.cs index cb7e7164867..8d568b87e2d 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnectionInternal.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnectionInternal.cs @@ -109,10 +109,7 @@ public SqliteConnectionInternal(SqliteConnectionStringBuilder connectionOptions, // NB: SQLite doesn't support parameters in PRAGMA statements, so we escape the value using the // quote function before concatenating. - var quotedPassword = ExecuteScalar( - "SELECT quote($password);", - connectionOptions.Password, - connectionOptions.DefaultTimeout); + var quotedPassword = QuotePassword(connectionOptions.Password); ExecuteNonQuery( "PRAGMA key = " + quotedPassword + ";", connectionOptions.DefaultTimeout); @@ -196,6 +193,29 @@ public void Dispose() _pool = null; } + private string QuotePassword(string password) + { + SqliteException.ThrowExceptionForRC(sqlite3_open(":memory:", out var db), db); + try + { + SqliteException.ThrowExceptionForRC(sqlite3_prepare_v2(db, "SELECT quote($password);", out var stmt), db); + try + { + sqlite3_bind_text(stmt, 1, password); + SqliteException.ThrowExceptionForRC(sqlite3_step(stmt), db); + return sqlite3_column_text(stmt, 0).utf8_to_string(); + } + finally + { + stmt.Dispose(); + } + } + finally + { + db.Dispose(); + } + } + private void ExecuteNonQuery(string sql, int timeout) => RetryWhileBusy(() => sqlite3_exec(_db, sql), timeout);