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 <axel.spoerl@qt.io>
This commit is contained in:
Christian Ehrlicher 2024-11-08 13:16:21 +01:00
parent c93e98648c
commit 38277a88f1

View File

@ -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);