summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Reininghaus <frank78ac@googlemail.com>2011-05-29 13:41:14 (GMT)
committerFrank Reininghaus <frank78ac@googlemail.com>2011-05-31 18:28:27 (GMT)
commit8d885c97b483b21ee13b6bf9539a1cb7e529102a (patch)
tree7746a2bd9fa7a29e2e32ae583c56d23226b8c41d
parentaa705f2a16d437aad24df8846476bcc5e44c73bd (diff)
Fix possible crash in KDirModel if the root item is deleted or moved
If the root item of the dir model is deleted, but it is not the first item in the list that KDirModelPrivate::_k_slotDeleteItems(...) gets from the dir lister, a crash may result because KDirModelPrivate::removeFromNodeHash(...) calls isDir() for a null KFileItem. This commit extends the protection agains this kind of crash that has been introduced in c8939409eed00420fb43ff22cfc6c9092e4da7e5 for the first item to the rest of the list. BUG: 196695 FIXED-IN: 4.6.4 (cherry picked from commit 83538b4339a65c90764975f01a4b9bafbabd9595)
-rw-r--r--kio/kio/kdirmodel.cpp5
-rw-r--r--kio/tests/kdirmodeltest.cpp21
-rw-r--r--kio/tests/kdirmodeltest.h1
3 files changed, 27 insertions, 0 deletions
diff --git a/kio/kio/kdirmodel.cpp b/kio/kio/kdirmodel.cpp
index 6bf57be..2243e27 100644
--- a/kio/kio/kdirmodel.cpp
+++ b/kio/kio/kdirmodel.cpp
@@ -489,6 +489,11 @@ void KDirModelPrivate::_k_slotDeleteItems(const KFileItemList& items)
kWarning(7008) << "No node found for item that was just removed:" << url;
continue;
}
+ if (!node->parent()) {
+ // The root node has been deleted, but it was not first in the list 'items'.
+ // see https://bugs.kde.org/show_bug.cgi?id=196695
+ return;
+ }
}
rowNumbers.setBit(node->rowNumber(), 1); // O(n)
removeFromNodeHash(node, url);
diff --git a/kio/tests/kdirmodeltest.cpp b/kio/tests/kdirmodeltest.cpp
index f2003cd..c6a95e0 100644
--- a/kio/tests/kdirmodeltest.cpp
+++ b/kio/tests/kdirmodeltest.cpp
@@ -1066,6 +1066,27 @@ void KDirModelTest::testSmb()
}
}
+class MyDirLister : public KDirLister
+{
+public:
+ void emitItemsDeleted(const KFileItemList& items) { emit itemsDeleted(items); }
+};
+
+void KDirModelTest::testBug196695()
+{
+ KFileItem rootItem(KUrl(m_tempDir->name()), QString(), KFileItem::Unknown);
+ KFileItem childItem(KUrl(QString(m_tempDir->name() + "toplevelfile_1")), QString(), KFileItem::Unknown);
+
+ KFileItemList list;
+ // Important: the root item must not be first in the list to trigger bug 196695
+ list << childItem << rootItem;
+
+ MyDirLister* dirLister = static_cast<MyDirLister*>(m_dirModel->dirLister());
+ dirLister->emitItemsDeleted(list);
+
+ fillModel(true);
+}
+
void KDirModelTest::testDeleteFile()
{
fillModel(false);
diff --git a/kio/tests/kdirmodeltest.h b/kio/tests/kdirmodeltest.h
index 3572a2f..85e9a34 100644
--- a/kio/tests/kdirmodeltest.h
+++ b/kio/tests/kdirmodeltest.h
@@ -60,6 +60,7 @@ private Q_SLOTS:
void testRemoteUrlWithHost();
void testZipFile();
void testSmb();
+ void testBug196695();
// These tests must be done last
void testDeleteFile();