From 0de6c52bfe2433eca768a5f6fe9d5f08a545c254 Mon Sep 17 00:00:00 2001
From: Samuel Gaist <samuel.gaist@edeltech.ch>
Date: Fri, 28 Aug 2015 18:20:04 +0200
Subject: [PATCH] Fix QMYSQL plugin database connection setup check

Opening a connection to an e.g. inactive server will return true
regardless of the server accessibility.
This patch aims to fix the current checks done.

The first one is an allocation check which should only fail if there's
not enough memory but is currently wrote as if the connection failed
there.

The second check that is "failing" is the connection setup. The return
value should either be NULL or the same value provided as first
parameter. That is now verified.

[ChangeLog][QtSql][QSqlDatabase] Fixed a bug where opening a
connection to a MySQL database using the QMYSQL plugin would always
return true even if the server was unreachable. This bug could
also lead to crashes depending on the platform used.

Task-number: QTBUG-47784
Task-number: QTBUG-47452
Change-Id: I91651684b5a342eaa7305473e26d8371b35396c4
Reviewed-by: Andy Shaw <andy.shaw@theqtcompany.com>
---
 src/sql/drivers/mysql/qsql_mysql.cpp | 41 ++++++++++++++++------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index d901008e007..8ac7f765e29 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -1282,19 +1282,21 @@ bool QMYSQLDriver::open(const QString& db,
         if (writeTimeout != 0)
             mysql_options(d->mysql, MYSQL_OPT_WRITE_TIMEOUT, &writeTimeout);
 #endif
-        if (mysql_real_connect(d->mysql,
-                               host.isNull() ? static_cast<const char *>(0)
-                                             : host.toLocal8Bit().constData(),
-                               user.isNull() ? static_cast<const char *>(0)
-                                             : user.toLocal8Bit().constData(),
-                               password.isNull() ? static_cast<const char *>(0)
-                                                 : password.toLocal8Bit().constData(),
-                               db.isNull() ? static_cast<const char *>(0)
-                                           : db.toLocal8Bit().constData(),
-                               (port > -1) ? port : 0,
-                               unixSocket.isNull() ? static_cast<const char *>(0)
-                                           : unixSocket.toLocal8Bit().constData(),
-                               optionFlags)) {
+        MYSQL *mysql = mysql_real_connect(d->mysql,
+                                          host.isNull() ? static_cast<const char *>(0)
+                                                        : host.toLocal8Bit().constData(),
+                                          user.isNull() ? static_cast<const char *>(0)
+                                                        : user.toLocal8Bit().constData(),
+                                          password.isNull() ? static_cast<const char *>(0)
+                                                            : password.toLocal8Bit().constData(),
+                                          db.isNull() ? static_cast<const char *>(0)
+                                                      : db.toLocal8Bit().constData(),
+                                          (port > -1) ? port : 0,
+                                          unixSocket.isNull() ? static_cast<const char *>(0)
+                                                              : unixSocket.toLocal8Bit().constData(),
+                                          optionFlags);
+
+        if (mysql == d->mysql) {
             if (!db.isEmpty() && mysql_select_db(d->mysql, db.toLocal8Bit().constData())) {
                 setLastError(qMakeError(tr("Unable to open database '%1'").arg(db), QSqlError::ConnectionError, d));
                 mysql_close(d->mysql);
@@ -1305,12 +1307,17 @@ bool QMYSQLDriver::open(const QString& db,
             if (reconnect)
                 mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect);
 #endif
+        } else {
+            setLastError(qMakeError(tr("Unable to connect"),
+                         QSqlError::ConnectionError, d));
+            mysql_close(d->mysql);
+            d->mysql = NULL;
+            setOpenError(true);
+            return false;
         }
     } else {
-        setLastError(qMakeError(tr("Unable to connect"),
-                     QSqlError::ConnectionError, d));
-        mysql_close(d->mysql);
-        d->mysql = NULL;
+        setLastError(qMakeError(tr("Failed to allocated data"),
+                     QSqlError::UnknownError, d));
         setOpenError(true);
         return false;
     }
-- 
GitLab