diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-12-13 17:17:56 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-14 04:57:30 +0100 |
commit | 13eb07b3a63d53abcabfa60659fd829051db66a3 (patch) | |
tree | 240855ed20e16aff046bee7d7808fbf4452d2710 /src/quick/util | |
parent | fe52727baea9986882461e2ea15e9e64b96e4c61 (diff) |
Fix crash when items are moved in model.
When erasing an item we need to backtrack to the previous item so the
next iteration doesn't skip an item. In the worst case the next item
is the last and a failure to backtrack will cause the loop to wrap
around and run over the list again.
Task-number: QTBUG-23107
Change-Id: I82156f6fc1f7973ba11f09a4694230c77c293757
Reviewed-by: Bea Lam <bea.lam@nokia.com>
Diffstat (limited to 'src/quick/util')
-rw-r--r-- | src/quick/util/qdeclarativelistcompositor.cpp | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/src/quick/util/qdeclarativelistcompositor.cpp b/src/quick/util/qdeclarativelistcompositor.cpp index d73d76e386..e43a8a771f 100644 --- a/src/quick/util/qdeclarativelistcompositor.cpp +++ b/src/quick/util/qdeclarativelistcompositor.cpp @@ -872,9 +872,7 @@ void QDeclarativeListCompositor::listItemsRemoved( { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << *removals) - for (iterator it(m_ranges.next, 0, Default, m_groupCount); - *it != &m_ranges && !removals->isEmpty(); - *it = it->next) { + for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) { if (it->list != list || it->flags == CacheFlag) { it.incrementIndexes(it->count); continue; @@ -920,21 +918,20 @@ void QDeclarativeListCompositor::listItemsRemoved( translatedRemoval.moveId = ++moveId; movedFlags->append(MovedFlags(moveId, it->flags & ~AppendFlag)); - removal = removals->insert(removal, QDeclarativeChangeSet::Remove( - removal->index, removeCount, translatedRemoval.moveId)); - ++removal; - insertion = insertions->insert(insertion, QDeclarativeChangeSet::Insert( - insertion->index, removeCount, translatedRemoval.moveId)); - ++insertion; - - removal->count -= removeCount; - insertion->index += removeCount; - insertion->count -= removeCount; - if (removal->count == 0) { - removal = removals->erase(removal); - insertion = insertions->erase(insertion); - --removal; - --insertion; + if (removeCount < removal->count) { + removal = removals->insert(removal, QDeclarativeChangeSet::Remove( + removal->index, removeCount, translatedRemoval.moveId)); + ++removal; + insertion = insertions->insert(insertion, QDeclarativeChangeSet::Insert( + insertion->index, removeCount, translatedRemoval.moveId)); + ++insertion; + + removal->count -= removeCount; + insertion->index += removeCount; + insertion->count -= removeCount; + } else { + removal->moveId = translatedRemoval.moveId; + insertion->moveId = translatedRemoval.moveId; } } else { if (offset > 0) { @@ -989,7 +986,7 @@ void QDeclarativeListCompositor::listItemsRemoved( it->previous->count += it->count; it->previous->flags = it->flags; it.incrementIndexes(it->count); - *it = erase(*it); + *it = erase(*it)->previous; removed = true; } } |