diff options
author | Christian Ehrlicher <[email protected]> | 2024-11-08 13:16:21 +0100 |
---|---|---|
committer | Christian Ehrlicher <[email protected]> | 2025-01-22 05:16:02 +0000 |
commit | 38277a88f1dd69de6e031bc8313c8d5beadf6bd0 (patch) | |
tree | 178d2b2cd5aa99c73f224dcfb4209b6b12207404 | |
parent | c93e98648c9250c5731bf9af9d44a81946419514 (diff) |
SQL/ODBC: escape values in connection string
The previous attempt to escape invalid characters for username/password
did not work for e.g. '}' or '{'. The msdn documentation is somewhat
inconsitent here but after testing it looks like putting the
username/password inside '{' and '}' no matter if needed or not is the
easiest way. We have to escape '}' by doubling it though.
No need to escape the DSN - testing on windows revealed that ';' is not
allowed in there and '\'' and '"' at the start of the DSN is perfectly
fine without any escaping.
Pick-to: 6.9 6.8
Fixes: QTBUG-122642
Change-Id: I04d007d343dd65eb0dbc0252518843eb43cd9ab8
Reviewed-by: Axel Spoerl <[email protected]>
-rw-r--r-- | src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index 9a890c044cf..f2f2619404c 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -1920,18 +1920,6 @@ bool QODBCDriver::open(const QString & db, int, const QString& connOpts) { - const auto ensureEscaped = [](QString arg) -> QString { - QChar quoteChar; - if (arg.startsWith(u'"')) - quoteChar = u'\''; - else if (arg.startsWith(u'\'')) - quoteChar = u'"'; - else if (arg.contains(u';')) - quoteChar = u'"'; - else - return arg; - return quoteChar + arg + quoteChar; - }; Q_D(QODBCDriver); if (isOpen()) close(); @@ -1967,17 +1955,20 @@ bool QODBCDriver::open(const QString & db, QString connQStr; // support the "DRIVER={SQL SERVER};SERVER=blah" syntax if (db.contains(".dsn"_L1, Qt::CaseInsensitive)) - connQStr = "FILEDSN="_L1 + ensureEscaped(db); + connQStr = "FILEDSN="_L1 + db; else if (db.contains("DRIVER="_L1, Qt::CaseInsensitive) || db.contains("SERVER="_L1, Qt::CaseInsensitive)) connQStr = db; else - connQStr = "DSN="_L1 + ensureEscaped(db); + connQStr = "DSN="_L1 + db; + const auto escapeUserPassword = [](QString arg) -> QString { + return u'{' + arg.replace(u'}', u'{') + u'}'; + }; if (!user.isEmpty()) - connQStr += ";UID="_L1 + ensureEscaped(user); + connQStr += ";UID="_L1 + escapeUserPassword(user); if (!password.isEmpty()) - connQStr += ";PWD="_L1 + ensureEscaped(password); + connQStr += ";PWD="_L1 + escapeUserPassword(password); SQLSMALLINT cb; QVarLengthArray<SQLTCHAR, 1024> connOut(1024); |