From e4bd73dc54542fe16121825c2a369b7f863e0de8 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 16 Jan 2021 21:04:09 +0100 Subject: QSql/MariaDB/MySQL: use utf-8 as encoding for username and password The mariadb driver sets the encoding for the connection to utf-8 but only after the username and password was already set. Therefore non-ascii characters were not correctly encoded when the local character set was not the default one from the database. Move mysql_set_character_set() above the username/password setting and encode all as utf-8 instead local8Bit. Fixes: QTBUG-55444 Change-Id: Iff7ee24159d54b578cd854e620aa814d72da3801 Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/mysql/qsql_mysql.cpp | 49 ++++++++++++----------------- 1 file changed, 20 insertions(+), 29 deletions(-) (limited to 'src/plugins/sqldrivers') diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp index 770e7b16d8..554f4d91a4 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp @@ -1213,26 +1213,26 @@ bool QMYSQLDriver::open(const QString& db, } } - if (!(d->mysql = mysql_init((MYSQL*) 0))) { + if (!(d->mysql = mysql_init(nullptr))) { setLastError(qMakeError(tr("Unable to allocate a MYSQL object"), QSqlError::ConnectionError, d)); setOpenError(true); return false; } + // try utf8 with non BMP first, utf8 (BMP only) if that fails + if (mysql_set_character_set(d->mysql, "utf8mb4")) + if (mysql_set_character_set(d->mysql, "utf8")) + qWarning() << "MySQL: Unable to set the client character set to utf8."; + if (!sslKey.isNull() || !sslCert.isNull() || !sslCA.isNull() || !sslCAPath.isNull() || !sslCipher.isNull()) { mysql_ssl_set(d->mysql, - sslKey.isNull() ? static_cast(0) - : QFile::encodeName(sslKey).constData(), - sslCert.isNull() ? static_cast(0) - : QFile::encodeName(sslCert).constData(), - sslCA.isNull() ? static_cast(0) - : QFile::encodeName(sslCA).constData(), - sslCAPath.isNull() ? static_cast(0) - : QFile::encodeName(sslCAPath).constData(), - sslCipher.isNull() ? static_cast(0) - : sslCipher.toLocal8Bit().constData()); + sslKey.isNull() ? nullptr : sslKey.toUtf8().constData(), + sslCert.isNull() ? nullptr : sslCert.toUtf8().constData(), + sslCA.isNull() ? nullptr : sslCA.toUtf8().constData(), + sslCAPath.isNull() ? nullptr : sslCAPath.toUtf8().constData(), + sslCipher.isNull() ? nullptr : sslCipher.toUtf8().constData()); } if (connectTimeout != 0) @@ -1241,27 +1241,18 @@ bool QMYSQLDriver::open(const QString& db, mysql_options(d->mysql, MYSQL_OPT_READ_TIMEOUT, &readTimeout); if (writeTimeout != 0) mysql_options(d->mysql, MYSQL_OPT_WRITE_TIMEOUT, &writeTimeout); + MYSQL *mysql = mysql_real_connect(d->mysql, - host.isNull() ? static_cast(0) - : host.toLocal8Bit().constData(), - user.isNull() ? static_cast(0) - : user.toLocal8Bit().constData(), - password.isNull() ? static_cast(0) - : password.toLocal8Bit().constData(), - db.isNull() ? static_cast(0) - : db.toLocal8Bit().constData(), + host.isNull() ? nullptr : host.toUtf8().constData(), + user.isNull() ? nullptr : user.toUtf8().constData(), + password.isNull() ? nullptr : password.toUtf8().constData(), + db.isNull() ? nullptr : db.toUtf8().constData(), (port > -1) ? port : 0, - unixSocket.isNull() ? static_cast(0) - : unixSocket.toLocal8Bit().constData(), + unixSocket.isNull() ? nullptr : unixSocket.toUtf8().constData(), optionFlags); - // try utf8 with non BMP first, utf8 (BMP only) if that fails - if (mysql_set_character_set(d->mysql, "utf8mb4")) - if (mysql_set_character_set(d->mysql, "utf8")) - qWarning() << "MySQL: Unable to set the client character set to utf8."; - if (mysql == d->mysql) { - if (!db.isEmpty() && mysql_select_db(d->mysql, db.toLocal8Bit().constData())) { + if (!db.isEmpty() && mysql_select_db(d->mysql, db.toUtf8().constData())) { setLastError(qMakeError(tr("Unable to open database '%1'").arg(db), QSqlError::ConnectionError, d)); mysql_close(d->mysql); setOpenError(true); @@ -1273,7 +1264,7 @@ bool QMYSQLDriver::open(const QString& db, setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); mysql_close(d->mysql); - d->mysql = NULL; + d->mysql = nullptr; setOpenError(true); return false; } @@ -1369,7 +1360,7 @@ QSqlRecord QMYSQLDriver::record(const QString& tablename) const QSqlRecord info; if (!isOpen()) return info; - MYSQL_RES* r = mysql_list_fields(d->mysql, table.toLocal8Bit().constData(), 0); + MYSQL_RES* r = mysql_list_fields(d->mysql, table.toUtf8().constData(), 0); if (!r) { return info; } -- cgit v1.2.3