diff options
| author | Frank Reininghaus <[email protected]> | 2014-06-04 21:48:19 +0200 |
|---|---|---|
| committer | Frank Reininghaus <[email protected]> | 2014-06-04 21:49:02 +0200 |
| commit | 352f6441590a050099ee685b2284d1679f733c97 (patch) | |
| tree | e9547883bc442b94569496931b3e22b5c0689fa7 /src/kitemviews | |
| parent | 96c34cfe650cef24bcfd6cfa6977c3b0ccb77281 (diff) | |
Fix possible crash if a kioslave adds multiple items with the same URL
When opening the URL "man:", there are multiple items with the same
name (for example, _exit is shown twice here). When opening a new tab,
the kioslave reports some items as deleted (I have not quite understood
why). The problem is that it reports some of the duplicate items twice
in the list of deleted items. This confused KFileItemModel and
corrupted the internal data structures, and finally, caused a crash.
The fix is to remove all duplicates from
KItemRangeList::fromSortedContainer(const Container& container).
New unit tests included.
BUG: 335672
REVIEW: 118507
FIXED-IN: 4.13.2
Diffstat (limited to 'src/kitemviews')
| -rw-r--r-- | src/kitemviews/kfileitemmodel.cpp | 36 | ||||
| -rw-r--r-- | src/kitemviews/kitemrange.h | 10 |
2 files changed, 44 insertions, 2 deletions
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index de3c3eb22..b3b926c3a 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -395,7 +395,41 @@ int KFileItemModel::index(const KUrl& url) const index = m_items.value(urlToFind, -1); } - Q_ASSERT(index >= 0 || m_items.count() == m_itemData.count()); + if (index < 0) { + // The item could not be found, even though all items from m_itemData + // should be in m_items now. We print some diagnostic information which + // might help to find the cause of the problem, but only once. This + // prevents that obtaining and printing the debugging information + // wastes CPU cycles and floods the shell or .xsession-errors. + static bool printDebugInfo = true; + + if (m_items.count() != m_itemData.count() && printDebugInfo) { + printDebugInfo = false; + + kWarning() << "The model is in an inconsistent state."; + kWarning() << "m_items.count() ==" << m_items.count(); + kWarning() << "m_itemData.count() ==" << m_itemData.count(); + + // Check if there are multiple items with the same URL. + QMultiHash<KUrl, int> indexesForUrl; + for (int i = 0; i < m_itemData.count(); ++i) { + indexesForUrl.insert(m_itemData.at(i)->item.url(), i); + } + + foreach (const KUrl& url, indexesForUrl.uniqueKeys()) { + if (indexesForUrl.count(url) > 1) { + kWarning() << "Multiple items found with the URL" << url; + foreach (int index, indexesForUrl.values(url)) { + const ItemData* data = m_itemData.at(index); + kWarning() << "index" << index << ":" << data->item; + if (data->parent) { + kWarning() << "parent" << data->parent->item; + } + } + } + } + } + } return index; } diff --git a/src/kitemviews/kitemrange.h b/src/kitemviews/kitemrange.h index 70927b915..ecc03988d 100644 --- a/src/kitemviews/kitemrange.h +++ b/src/kitemviews/kitemrange.h @@ -78,7 +78,10 @@ KItemRangeList KItemRangeList::fromSortedContainer(const Container& container) int index = *it; int count = 1; - ++it; + // Remove duplicates, see https://bugs.kde.org/show_bug.cgi?id=335672 + while (it != end && *it == index) { + ++it; + } while (it != end) { if (*it == index + count) { @@ -89,6 +92,11 @@ KItemRangeList KItemRangeList::fromSortedContainer(const Container& container) count = 1; } ++it; + + // Remove duplicates, see https://bugs.kde.org/show_bug.cgi?id=335672 + while (it != end && *it == *(it - 1)) { + ++it; + } } result << KItemRange(index, count); |
