Sql: Fix heap-user-after-free for globally initialized db objects

Becaues the database objects were created as globals, there was a
possible use-after-free issue when deleting the objects on application
exit.

Move the initialization of the database objects into static variables
inside the test constructor.

As a drive-by, also add one missing test to the CMake projects.

Fixes: QTBUG-85357
Change-Id: I2c8f2c5daee96bb9d1d21dae37950a2da5ffdf27
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Alexandru Croitor 2020-06-30 18:49:57 +02:00
parent a046833176
commit fb55e1e71e
6 changed files with 55 additions and 13 deletions

View File

@ -33,7 +33,7 @@
#include "../qsqldatabase/tst_databases.h" #include "../qsqldatabase/tst_databases.h"
const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase())); QString qtest;
class tst_QSqlQuery : public QObject class tst_QSqlQuery : public QObject
{ {
@ -271,6 +271,8 @@ private:
tst_QSqlQuery::tst_QSqlQuery() tst_QSqlQuery::tst_QSqlQuery()
{ {
static QSqlDatabase static_qtest_db = QSqlDatabase();
qtest = qTableName("qtest", __FILE__, static_qtest_db);
} }
tst_QSqlQuery::~tst_QSqlQuery() tst_QSqlQuery::~tst_QSqlQuery()

View File

@ -36,7 +36,7 @@
#include <QtSql> #include <QtSql>
#include "qdebug.h" #include "qdebug.h"
const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase())); QString qtest;
// set this define if Oracle is built with threading support // set this define if Oracle is built with threading support
//#define QOCI_THREADED //#define QOCI_THREADED
@ -263,6 +263,8 @@ private:
tst_QSqlThread::tst_QSqlThread() tst_QSqlThread::tst_QSqlThread()
: threadFinishedCount(0) : threadFinishedCount(0)
{ {
static QSqlDatabase static_qtest_db = QSqlDatabase();
qtest = qTableName("qtest", __FILE__, static_qtest_db);
} }
tst_QSqlThread::~tst_QSqlThread() tst_QSqlThread::~tst_QSqlThread()

View File

@ -1,6 +1,8 @@
# Generated from models.pro.
add_subdirectory(qsqlrelationaltablemodel) add_subdirectory(qsqlrelationaltablemodel)
add_subdirectory(qsqltablemodel) add_subdirectory(qsqltablemodel)
if(TARGET Qt::Widgets) if(TARGET Qt::Widgets)
add_subdirectory(qsqlquerymodel) add_subdirectory(qsqlquerymodel)
add_subdirectory(qsqlrelationaldelegate)
endif() endif()

View File

@ -34,8 +34,8 @@
#include "../../kernel/qsqldatabase/tst_databases.h" #include "../../kernel/qsqldatabase/tst_databases.h"
const QString reltest1(qTableName("reltest1", __FILE__, QSqlDatabase())), QString reltest1;
reltest2(qTableName("reltest2", __FILE__, QSqlDatabase())); QString reltest2;
class tst_QSqlRelationalDelegate : public QObject class tst_QSqlRelationalDelegate : public QObject
{ {
@ -45,6 +45,7 @@ public:
void recreateTestTables(QSqlDatabase); void recreateTestTables(QSqlDatabase);
tst_Databases dbs; tst_Databases dbs;
tst_QSqlRelationalDelegate();
public slots: public slots:
void initTestCase_data(); void initTestCase_data();
@ -59,6 +60,14 @@ private:
void dropTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db);
}; };
tst_QSqlRelationalDelegate::tst_QSqlRelationalDelegate()
{
static QSqlDatabase static_qtest_db_1 = QSqlDatabase();
reltest1 = qTableName("reltest1", __FILE__, static_qtest_db_1);
static QSqlDatabase static_qtest_db_2 = QSqlDatabase();
reltest2 = qTableName("reltest2", __FILE__, static_qtest_db_2);
}
void tst_QSqlRelationalDelegate::initTestCase_data() void tst_QSqlRelationalDelegate::initTestCase_data()
{ {

View File

@ -32,11 +32,11 @@
#include "../../kernel/qsqldatabase/tst_databases.h" #include "../../kernel/qsqldatabase/tst_databases.h"
const QString reltest1(qTableName("reltest1", __FILE__, QSqlDatabase())), QString reltest1;
reltest2(qTableName("reltest2", __FILE__, QSqlDatabase())), QString reltest2;
reltest3(qTableName("reltest3", __FILE__, QSqlDatabase())), QString reltest3;
reltest4(qTableName("reltest4", __FILE__, QSqlDatabase())), QString reltest4;
reltest5(qTableName("reltest5", __FILE__, QSqlDatabase())); QString reltest5;
class tst_QSqlRelationalTableModel : public QObject class tst_QSqlRelationalTableModel : public QObject
{ {
@ -44,6 +44,7 @@ class tst_QSqlRelationalTableModel : public QObject
public: public:
void recreateTestTables(QSqlDatabase); void recreateTestTables(QSqlDatabase);
tst_QSqlRelationalTableModel();
tst_Databases dbs; tst_Databases dbs;
@ -83,6 +84,23 @@ private:
void dropTestTables( QSqlDatabase db ); void dropTestTables( QSqlDatabase db );
}; };
tst_QSqlRelationalTableModel::tst_QSqlRelationalTableModel()
{
static QSqlDatabase static_qtest_db_1 = QSqlDatabase();
reltest1 = qTableName("reltest1", __FILE__, static_qtest_db_1);
static QSqlDatabase static_qtest_db_2 = QSqlDatabase();
reltest2 = qTableName("reltest2", __FILE__, static_qtest_db_2);
static QSqlDatabase static_qtest_db_3 = QSqlDatabase();
reltest3 = qTableName("reltest3", __FILE__, static_qtest_db_3);
static QSqlDatabase static_qtest_db_4 = QSqlDatabase();
reltest4 = qTableName("reltest4", __FILE__, static_qtest_db_4);
static QSqlDatabase static_qtest_db_5 = QSqlDatabase();
reltest5 = qTableName("reltest5", __FILE__, static_qtest_db_5);
}
void tst_QSqlRelationalTableModel::initTestCase_data() void tst_QSqlRelationalTableModel::initTestCase_data()
{ {

View File

@ -34,9 +34,9 @@
#include <QThread> #include <QThread>
#include <QElapsedTimer> #include <QElapsedTimer>
const QString test(qTableName("test", __FILE__, QSqlDatabase())), QString test;
test2(qTableName("test2", __FILE__, QSqlDatabase())), QString test2;
test3(qTableName("test3", __FILE__, QSqlDatabase())); QString test3;
// In order to catch when the warning message occurs, indicating that the database belongs to another // In order to catch when the warning message occurs, indicating that the database belongs to another
// thread, we have to install our own message handler. To ensure that the test reporting still happens // thread, we have to install our own message handler. To ensure that the test reporting still happens
@ -164,6 +164,15 @@ private:
tst_QSqlTableModel::tst_QSqlTableModel() tst_QSqlTableModel::tst_QSqlTableModel()
{ {
static QSqlDatabase static_qtest_db_1 = QSqlDatabase();
test = qTableName("test1", __FILE__, static_qtest_db_1);
static QSqlDatabase static_qtest_db_2 = QSqlDatabase();
test2 = qTableName("test2", __FILE__, static_qtest_db_2);
static QSqlDatabase static_qtest_db_3 = QSqlDatabase();
test3 = qTableName("test3", __FILE__, static_qtest_db_3);
QVERIFY(dbs.open()); QVERIFY(dbs.open());
} }