Fix sorting issue when sorting by "size"

Root cause of the issue was an overflow in:
result = a - b;
where result is 'int' and a and b are 'KIO::filesize_t'.

BUG: 293086
FIXED-IN: 4.8.1
This commit is contained in:
Peter Penz 2012-02-02 15:58:42 +01:00
parent 9ef4b489c0
commit a551996848
2 changed files with 26 additions and 6 deletions

View file

@ -1301,21 +1301,24 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const
case SizeRole: {
if (itemA.isDir()) {
Q_ASSERT(itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above
// See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
Q_ASSERT(itemB.isDir());
const QVariant valueA = a->values.value("size");
const QVariant valueB = b->values.value("size");
if (valueA.isNull()) {
if (valueA.isNull() && valueB.isNull()) {
result = 0;
} else if (valueA.isNull()) {
result = -1;
} else if (valueB.isNull()) {
result = +1;
} else {
result = valueA.value<KIO::filesize_t>() - valueB.value<KIO::filesize_t>();
result = fileSizeCompare(valueA.value<KIO::filesize_t>(), valueB.value<KIO::filesize_t>());
}
} else {
Q_ASSERT(!itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above
result = itemA.size() - itemB.size();
// See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
Q_ASSERT(!itemB.isDir());
result = fileSizeCompare(itemA.size(), itemB.size());
}
break;
}
@ -1940,4 +1943,15 @@ KFileItemList KFileItemModel::childItems(const KFileItem& item) const
return items;
}
int KFileItemModel::fileSizeCompare(KIO::filesize_t a, KIO::filesize_t b)
{
if (a > b) {
return +1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
#include "kfileitemmodel.moc"

View file

@ -330,6 +330,12 @@ private:
*/
KFileItemList childItems(const KFileItem& item) const;
/**
* Helper method for sortRoleCompare().
* @return 0 if both sizes are equal, +1 if a > b and -1 if a < b.
*/
static int fileSizeCompare(KIO::filesize_t a, KIO::filesize_t b);
private:
QWeakPointer<KDirLister> m_dirLister;