summaryrefslogtreecommitdiffstats
path: root/src/sql
diff options
context:
space:
mode:
authorMark Brand <mabrand@mabrand.nl>2012-09-25 23:50:01 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-05 03:16:12 +0200
commit5fe272f68a59724022f545ac15c2f7d758c5ea86 (patch)
tree8824c1a0c6afd0dd858473c13404c3b8f4c90d45 /src/sql
parentc86ed49a7989adb3e2e3c42794e44609f12ce493 (diff)
QSqlTableModel: fix segfault when overriding selectRow()
The STL-style iteration over the cache in submitAll() assumed the iterator would remain valid until reaching cache.end(). This failed to consider that virtual selectRow() might be overridden so that it removes rows from the cache. For example, it might call select() which would empty the cache. The new approach checks at each iteration whether the row is still in the cache. Using foreach here is justified by its fitness for purpose and readability. New test included. Change-Id: Idee8807ede239c3ba56ff1604574c49f47385ad2 Reviewed-by: David Faure (fixes for KDE) <faure@kde.org>
Diffstat (limited to 'src/sql')
-rw-r--r--src/sql/models/qsqltablemodel.cpp23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 95cd0d80d2..56838a4e8f 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -718,20 +718,25 @@ bool QSqlTableModel::submitAll()
bool success = true;
- for (QSqlTableModelPrivate::CacheMap::Iterator it = d->cache.begin();
- it != d->cache.end(); ++it) {
- if (it.value().submitted())
+ foreach (int row, d->cache.keys()) {
+ // be sure cache *still* contains the row since overriden selectRow() could have called select()
+ QSqlTableModelPrivate::CacheMap::iterator it = d->cache.find(row);
+ if (it == d->cache.end())
continue;
- switch (it.value().op()) {
+ QSqlTableModelPrivate::ModifiedRow &mrow = it.value();
+ if (mrow.submitted())
+ continue;
+
+ switch (mrow.op()) {
case QSqlTableModelPrivate::Insert:
- success = insertRowIntoTable(it.value().rec());
+ success = insertRowIntoTable(mrow.rec());
break;
case QSqlTableModelPrivate::Update:
- success = updateRowInTable(it.key(), it.value().rec());
+ success = updateRowInTable(row, mrow.rec());
break;
case QSqlTableModelPrivate::Delete:
- success = deleteRowFromTable(it.key());
+ success = deleteRowFromTable(row);
break;
case QSqlTableModelPrivate::None:
Q_ASSERT_X(false, "QSqlTableModel::submitAll()", "Invalid cache operation");
@@ -739,9 +744,9 @@ bool QSqlTableModel::submitAll()
}
if (success) {
- it.value().setSubmitted();
+ mrow.setSubmitted();
if (d->strategy != OnManualSubmit)
- success = selectRow(it.key());
+ success = selectRow(row);
}
if (!success)