]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Fix crashes in KFileItemModel::removeItems()
authorFrank Reininghaus <frank78ac@googlemail.com>
Tue, 29 Jan 2013 18:08:28 +0000 (19:08 +0100)
committerFrank Reininghaus <frank78ac@googlemail.com>
Tue, 29 Jan 2013 18:08:28 +0000 (19:08 +0100)
These crashes were caused by the recent commit
ff3267c6dcd0f6d0621b3a96b5462a9581a03883. 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

src/kitemviews/kfileitemmodel.cpp

index ab39e55e592f8af0b2aa234b5b52f6b4551b492a..1062aa5ea2a64f6400876387aac0f31cd3a6aee7 100644 (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.
     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) {
 
     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;
         }
             // 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());
     }
 
     m_itemData.erase(m_itemData.end() - indexesToRemove.count(), m_itemData.end());