Check driver validity before using it
Even though it is stated in the documentation that the SQL driver must remain valid during the life time of QSqlQuery, there are users who don't follow the rule. It's common that the destructor of QSqlQuery is called after the driver is already deleted. This fix checks the validity of the SQLite driver before QSqliteResult uses it in destructor. Task-number: QTBUG-16967 Change-Id: If0f52113f12e14102da1671cd6e12bdaa267114f Reviewed-by: Yunqiao Yin <charles.yin@nokia.com>
This commit is contained in:
parent
b9ebb65c77
commit
67be01ae50
@ -292,7 +292,9 @@ QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
|
|||||||
|
|
||||||
QSQLiteResult::~QSQLiteResult()
|
QSQLiteResult::~QSQLiteResult()
|
||||||
{
|
{
|
||||||
qobject_cast<const QSQLiteDriver *>(driver())->d->results.removeOne(this);
|
const QSqlDriver *sqlDriver = driver();
|
||||||
|
if (sqlDriver)
|
||||||
|
qobject_cast<const QSQLiteDriver *>(sqlDriver)->d->results.removeOne(this);
|
||||||
d->cleanup();
|
d->cleanup();
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "qsqlresult.h"
|
#include "qsqlresult.h"
|
||||||
#include "qvector.h"
|
#include "qvector.h"
|
||||||
#include "qsqldriver.h"
|
#include "qsqldriver.h"
|
||||||
|
#include "qpointer.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -64,7 +65,7 @@ class QSqlResultPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QSqlResultPrivate(QSqlResult* d)
|
QSqlResultPrivate(QSqlResult* d)
|
||||||
: q(d), sqldriver(0), idx(QSql::BeforeFirstRow), active(false),
|
: q(d), idx(QSql::BeforeFirstRow), active(false),
|
||||||
isSel(false), forwardOnly(false), precisionPolicy(QSql::LowPrecisionDouble), bindCount(0), binds(QSqlResult::PositionalBinding)
|
isSel(false), forwardOnly(false), precisionPolicy(QSql::LowPrecisionDouble), bindCount(0), binds(QSqlResult::PositionalBinding)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
QSqlResult* q;
|
QSqlResult* q;
|
||||||
const QSqlDriver* sqldriver;
|
QPointer<QSqlDriver> sqldriver;
|
||||||
int idx;
|
int idx;
|
||||||
QString sql;
|
QString sql;
|
||||||
bool active;
|
bool active;
|
||||||
@ -250,7 +251,7 @@ QString QSqlResultPrivate::namedToPositionalBinding()
|
|||||||
QSqlResult::QSqlResult(const QSqlDriver *db)
|
QSqlResult::QSqlResult(const QSqlDriver *db)
|
||||||
{
|
{
|
||||||
d = new QSqlResultPrivate(this);
|
d = new QSqlResultPrivate(this);
|
||||||
d->sqldriver = db;
|
d->sqldriver = const_cast<QSqlDriver *>(db);
|
||||||
if(db) {
|
if(db) {
|
||||||
setNumericalPrecisionPolicy(db->numericalPrecisionPolicy());
|
setNumericalPrecisionPolicy(db->numericalPrecisionPolicy());
|
||||||
}
|
}
|
||||||
|
@ -3135,6 +3135,7 @@ void tst_QSqlQuery::QTBUG_21884()
|
|||||||
*/
|
*/
|
||||||
void tst_QSqlQuery::QTBUG_16967()
|
void tst_QSqlQuery::QTBUG_16967()
|
||||||
{
|
{
|
||||||
|
QSqlQuery q2;
|
||||||
QFETCH(QString, dbName);
|
QFETCH(QString, dbName);
|
||||||
{
|
{
|
||||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||||
@ -3146,6 +3147,7 @@ void tst_QSqlQuery::QTBUG_16967()
|
|||||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||||
CHECK_DATABASE(db);
|
CHECK_DATABASE(db);
|
||||||
QSqlQuery q(db);
|
QSqlQuery q(db);
|
||||||
|
q2 = q;
|
||||||
q.prepare("CREATE TABLE t1 (id INTEGER PRIMARY KEY, str TEXT);");
|
q.prepare("CREATE TABLE t1 (id INTEGER PRIMARY KEY, str TEXT);");
|
||||||
db.close();
|
db.close();
|
||||||
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
||||||
@ -3154,8 +3156,9 @@ void tst_QSqlQuery::QTBUG_16967()
|
|||||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||||
CHECK_DATABASE(db);
|
CHECK_DATABASE(db);
|
||||||
QSqlQuery q(db);
|
QSqlQuery q(db);
|
||||||
q.prepare("CREATE TABLE t1 (id INTEGER PRIMARY KEY, str TEXT);");
|
q2 = q;
|
||||||
q.exec();
|
q2.prepare("CREATE TABLE t1 (id INTEGER PRIMARY KEY, str TEXT);");
|
||||||
|
q2.exec();
|
||||||
db.close();
|
db.close();
|
||||||
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
||||||
}
|
}
|
||||||
@ -3163,6 +3166,7 @@ void tst_QSqlQuery::QTBUG_16967()
|
|||||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||||
CHECK_DATABASE(db);
|
CHECK_DATABASE(db);
|
||||||
QSqlQuery q(db);
|
QSqlQuery q(db);
|
||||||
|
q2 = q;
|
||||||
q.exec("INSERT INTO t1 (id, str) VALUES(1, \"test1\");");
|
q.exec("INSERT INTO t1 (id, str) VALUES(1, \"test1\");");
|
||||||
db.close();
|
db.close();
|
||||||
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
||||||
@ -3171,6 +3175,7 @@ void tst_QSqlQuery::QTBUG_16967()
|
|||||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||||
CHECK_DATABASE(db);
|
CHECK_DATABASE(db);
|
||||||
QSqlQuery q(db);
|
QSqlQuery q(db);
|
||||||
|
q2 = q;
|
||||||
q.exec("SELECT * FROM t1;");
|
q.exec("SELECT * FROM t1;");
|
||||||
db.close();
|
db.close();
|
||||||
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
QCOMPARE(db.lastError().type(), QSqlError::NoError);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user