Check for null driver() before trying to exec()
QSqlQuery::exec() took for granted that it can dereference driver(), which should be true for all sane usage; however, it should not crash if used misguidedly. Added regression test, based on bug report's reproducer, which crashes without the fix. Fixes: QTBUG-100037 Pick-to: 6.3 6.2 5.15 5.12 Change-Id: I94600bc60f89e82a1121b418144006a683921a38 Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
parent
f172b964f6
commit
78eac57f3d
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtSql module of the Qt Toolkit.
|
** This file is part of the QtSql module of the Qt Toolkit.
|
||||||
@ -406,6 +406,10 @@ bool QSqlQuery::exec(const QString& query)
|
|||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
t.start();
|
t.start();
|
||||||
#endif
|
#endif
|
||||||
|
if (!driver()) {
|
||||||
|
qWarning("QSqlQuery::exec: called before driver has been set up");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (d->ref.loadRelaxed() != 1) {
|
if (d->ref.loadRelaxed() != 1) {
|
||||||
bool fo = isForwardOnly();
|
bool fo = isForwardOnly();
|
||||||
*this = QSqlQuery(driver()->createResult());
|
*this = QSqlQuery(driver()->createResult());
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
@ -70,6 +70,8 @@ private slots:
|
|||||||
void query_exec();
|
void query_exec();
|
||||||
void execErrorRecovery_data() { generic_data(); }
|
void execErrorRecovery_data() { generic_data(); }
|
||||||
void execErrorRecovery();
|
void execErrorRecovery();
|
||||||
|
void prematureExec_data() { generic_data(); }
|
||||||
|
void prematureExec();
|
||||||
void first_data() { generic_data(); }
|
void first_data() { generic_data(); }
|
||||||
void first();
|
void first();
|
||||||
void next_data() { generic_data(); }
|
void next_data() { generic_data(); }
|
||||||
@ -2878,6 +2880,35 @@ void tst_QSqlQuery::execErrorRecovery()
|
|||||||
QVERIFY_SQL( q, exec() );
|
QVERIFY_SQL( q, exec() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QSqlQuery::prematureExec()
|
||||||
|
{
|
||||||
|
QFETCH(QString, dbName);
|
||||||
|
// We only want the engine name, for addDatabase():
|
||||||
|
int cut = dbName.indexOf(QChar('@'));
|
||||||
|
if (cut < 0)
|
||||||
|
QSKIP("Failed to parse database type out of name");
|
||||||
|
dbName.truncate(cut);
|
||||||
|
cut = dbName.indexOf(QChar('_'));
|
||||||
|
if (cut >= 0)
|
||||||
|
dbName = dbName.sliced(cut + 1);
|
||||||
|
|
||||||
|
auto db = QSqlDatabase::addDatabase(dbName);
|
||||||
|
QSqlQuery q(db);
|
||||||
|
|
||||||
|
QTest::ignoreMessage(QtWarningMsg,
|
||||||
|
"QSqlDatabasePrivate::removeDatabase: connection "
|
||||||
|
"'qt_sql_default_connection' is still in use, all "
|
||||||
|
"queries will cease to work.");
|
||||||
|
QTest::ignoreMessage(QtWarningMsg,
|
||||||
|
"QSqlDatabasePrivate::addDatabase: duplicate connection name "
|
||||||
|
"'qt_sql_default_connection', old connection removed.");
|
||||||
|
auto otherDb = QSqlDatabase::addDatabase(dbName);
|
||||||
|
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
|
||||||
|
// QTBUG-100037: shouldn't crash !
|
||||||
|
QVERIFY(!q.exec("select stuff from TheVoid"));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QSqlQuery::lastInsertId()
|
void tst_QSqlQuery::lastInsertId()
|
||||||
{
|
{
|
||||||
QFETCH( QString, dbName );
|
QFETCH( QString, dbName );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user