Fix crash when an invalid filter is set
authorHonglei Zhang <honglei.zhang@nokia.com>
Wed, 7 Mar 2012 16:54:58 +0000 (18:54 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 30 Mar 2012 17:51:43 +0000 (19:51 +0200)
QSqlTableModel::headerData() generates a crash if an invalid filter
is set. QSqlQueryModel::indexInQuery() should check the index value
before applied to d->colOffsets[].
QSqlQueryModel::initRecordAndPrimaryIndex() is updated to sync the
size of rec and colOffsets.

Task-number: QTBUG-23879
Change-Id: Ic9f88bb288592aa6fb3c1415cc818632dadaab56
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
src/sql/models/qsqlquerymodel.cpp
src/sql/models/qsqltablemodel.cpp
tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp

index 341804f..fefb87d 100644 (file)
@@ -591,7 +591,8 @@ QModelIndex QSqlQueryModel::indexInQuery(const QModelIndex &item) const
 {
     Q_D(const QSqlQueryModel);
     if (item.column() < 0 || item.column() >= d->rec.count()
-        || !d->rec.isGenerated(item.column()))
+        || !d->rec.isGenerated(item.column())
+        || item.column() >= d->colOffsets.size())
         return QModelIndex();
     return createIndex(item.row(), item.column() - d->colOffsets[item.column()],
                        item.internalPointer());
index 20d2be3..f719897 100644 (file)
@@ -97,6 +97,7 @@ void QSqlTableModelPrivate::initRecordAndPrimaryIndex()
 {
     rec = db.record(tableName);
     primaryIndex = db.primaryIndex(tableName);
+    initColOffsets(rec.count());
 }
 
 void QSqlTableModelPrivate::clear()
@@ -332,7 +333,6 @@ void QSqlTableModel::setTable(const QString &tableName)
     clear();
     d->tableName = tableName;
     d->initRecordAndPrimaryIndex();
-    d->initColOffsets(d->rec.count());
 
     if (d->rec.count() == 0)
         d->error = QSqlError(QLatin1String("Unable to find table ") + d->tableName, QString(),
index afe2c59..2cea8b3 100644 (file)
@@ -133,6 +133,9 @@ private slots:
 
     void insertBeforeDelete_data() { generic_data(); }
     void insertBeforeDelete();
+
+    void invalidFilterAndHeaderData_data() { generic_data(); }
+    void invalidFilterAndHeaderData(); //QTBUG-23879
 private:
     void generic_data(const QString& engine=QString());
     void generic_data_with_strategies(const QString& engine=QString());
@@ -1681,5 +1684,25 @@ void tst_QSqlTableModel::insertBeforeDelete()
     QCOMPARE(model.rowCount(), 5);
 }
 
+void tst_QSqlTableModel::invalidFilterAndHeaderData()
+{
+    QFETCH(QString, dbName);
+    QSqlDatabase db = QSqlDatabase::database(dbName);
+    CHECK_DATABASE(db);
+
+    QSqlTableModel model(0, db);
+    model.setTable(test);
+    model.setEditStrategy(QSqlTableModel::OnManualSubmit);
+    QVERIFY_SQL(model, select());
+    QVERIFY_SQL(model, setHeaderData(0, Qt::Horizontal, "id"));
+    QVERIFY_SQL(model, setHeaderData(1, Qt::Horizontal, "name"));
+    QVERIFY_SQL(model, setHeaderData(2, Qt::Horizontal, "title"));
+
+    model.setFilter("some nonsense");
+
+    QVariant v = model.headerData(0, Qt::Horizontal, Qt::SizeHintRole);
+    QVERIFY(!v.isValid());
+}
+
 QTEST_MAIN(tst_QSqlTableModel)
 #include "tst_qsqltablemodel.moc"