Fix crashes in KFileItemModel::removeItems()

These crashes were caused by the recent commit
ff3267c6dc. It introduced two problems:

a) A logic error in the code that removes the ItemData pointers from
   m_itemData that could cause crashes if multiple item ranges are
   removed, and there were un-removed items behind the last one.
b) The implicit assumption that any call of removeItems() will actually
   result in items being removed in the model. This is incorrect if
   the model is first cleared and then the hidden-files setting is
   modified, which happens if "Save view properties for each folder" is
   enabled, and a folder where hidden files are shown is left. In that
   case, the dir lister emits itemsDeleted for the hidden items after
   they have been removed from the model due to the folder change.

I'll add a unit test covering these issues soon.

Many thanks to Romário Rios and Hrvoje Senjan for testing!

BUG: 314046
This commit is contained in:
Frank Reininghaus 2013-01-29 19:08:28 +01:00
parent 60a3b94c93
commit 8a8854a772

View file

@ -1064,6 +1064,10 @@ void KFileItemModel::removeItems(const KFileItemList& items)
}
}
if (indexesToRemove.isEmpty()) {
return;
}
std::sort(indexesToRemove.begin(), indexesToRemove.end());
// Step 2: Remove the ItemData pointers from the list m_itemData.
@ -1074,14 +1078,15 @@ void KFileItemModel::removeItems(const KFileItemList& items)
const int oldItemDataCount = m_itemData.count();
while (source < oldItemDataCount) {
if (nextRange < itemRanges.count() - 1 && source == itemRanges.at(nextRange).index) {
m_itemData[target] = m_itemData[source];
++target;
++source;
if (nextRange < itemRanges.count() && source == itemRanges.at(nextRange).index) {
// Skip the items in the next removed range.
source += itemRanges.at(nextRange).count;
++nextRange;
}
m_itemData[target] = m_itemData[source];
++target;
++source;
}
m_itemData.erase(m_itemData.end() - indexesToRemove.count(), m_itemData.end());