FolderStatusModel: fix potential assert

OCC::FolderStatusModel::slotUpdateDirectories: ASSERT: "parentInfo->_fetching" in file /home/olivier/kdegit/owncloud/mirall/src/gui/folderstatusmodel.cpp, line 599

This can happen if the structure of a folder is change while the user
expands the root folder. In this case, resetSubs() is called which
resets _fetching to false.
Instead, we need to keep a pointer to the job so we can abort it by
deleting it.
This commit is contained in:
Olivier Goffart 2018-03-27 12:17:29 +02:00 committed by Roeland Jago Douma
parent 6872cbda7e
commit f4f228de3e
No known key found for this signature in database
GPG key ID: F941078878347C0C
2 changed files with 11 additions and 10 deletions

View file

@ -547,7 +547,7 @@ bool FolderStatusModel::canFetchMore(const QModelIndex &parent) const
return false; return false;
} }
auto info = infoForIndex(parent); auto info = infoForIndex(parent);
if (!info || info->_fetched || info->_fetching) if (!info || info->_fetched || info->_fetchingJob)
return false; return false;
if (info->_hasError) { if (info->_hasError) {
// Keep showing the error to the user, it will be hidden when the account reconnects // Keep showing the error to the user, it will be hidden when the account reconnects
@ -561,10 +561,9 @@ void FolderStatusModel::fetchMore(const QModelIndex &parent)
{ {
auto info = infoForIndex(parent); auto info = infoForIndex(parent);
if (!info || info->_fetched || info->_fetching) if (!info || info->_fetched || info->_fetchingJob)
return; return;
info->resetSubs(this, parent); info->resetSubs(this, parent);
info->_fetching = true;
QString path = info->_folder->remotePath(); QString path = info->_folder->remotePath();
if (info->_path != QLatin1String("/")) { if (info->_path != QLatin1String("/")) {
if (!path.endsWith(QLatin1Char('/'))) { if (!path.endsWith(QLatin1Char('/'))) {
@ -580,6 +579,7 @@ void FolderStatusModel::fetchMore(const QModelIndex &parent)
} }
LsColJob *job = new LsColJob(_accountState->account(), path, this); LsColJob *job = new LsColJob(_accountState->account(), path, this);
info->_fetchingJob = job;
job->setProperties(QList<QByteArray>() << "resourcetype" job->setProperties(QList<QByteArray>() << "resourcetype"
<< "http://owncloud.org/ns:size" << "http://owncloud.org/ns:size"
<< "http://owncloud.org/ns:permissions" << "http://owncloud.org/ns:permissions"
@ -626,18 +626,18 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
if (!parentInfo) { if (!parentInfo) {
return; return;
} }
ASSERT(parentInfo->_fetching); // we should only get a result if we were doing a fetch ASSERT(parentInfo->_fetchingJob == job);
ASSERT(parentInfo->_subs.isEmpty()); ASSERT(parentInfo->_subs.isEmpty());
if (parentInfo->hasLabel()) { if (parentInfo->hasLabel()) {
beginRemoveRows(idx, 0, 0); beginRemoveRows(idx, 0, 0);
parentInfo->_lastErrorString.clear();
parentInfo->_hasError = false; parentInfo->_hasError = false;
parentInfo->_fetchingLabel = false; parentInfo->_fetchingLabel = false;
endRemoveRows(); endRemoveRows();
} }
parentInfo->_fetching = false; parentInfo->_lastErrorString.clear();
parentInfo->_fetchingJob = nullptr;
parentInfo->_fetched = true; parentInfo->_fetched = true;
QUrl url = parentInfo->_folder->remoteUrl(); QUrl url = parentInfo->_folder->remoteUrl();
@ -1229,7 +1229,7 @@ void FolderStatusModel::slotShowFetchProgress()
if (it.value().elapsed() > 800) { if (it.value().elapsed() > 800) {
auto idx = it.key(); auto idx = it.key();
auto *info = infoForIndex(idx); auto *info = infoForIndex(idx);
if (info && info->_fetching) { if (info && info->_fetchingJob) {
bool add = !info->hasLabel(); bool add = !info->hasLabel();
if (add) { if (add) {
beginInsertRows(idx, 0, 0); beginInsertRows(idx, 0, 0);
@ -1252,7 +1252,7 @@ bool FolderStatusModel::SubFolderInfo::hasLabel() const
void FolderStatusModel::SubFolderInfo::resetSubs(FolderStatusModel *model, QModelIndex index) void FolderStatusModel::SubFolderInfo::resetSubs(FolderStatusModel *model, QModelIndex index)
{ {
_fetched = false; _fetched = false;
_fetching = false; delete _fetchingJob;
if (hasLabel()) { if (hasLabel()) {
model->beginRemoveRows(index, 0, 0); model->beginRemoveRows(index, 0, 0);
_fetchingLabel = false; _fetchingLabel = false;

View file

@ -20,6 +20,7 @@
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QVector> #include <QVector>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QPointer>
class QNetworkReply; class QNetworkReply;
namespace OCC { namespace OCC {
@ -28,6 +29,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcFolderStatus)
class Folder; class Folder;
class ProgressInfo; class ProgressInfo;
class LsColJob;
/** /**
* @brief The FolderStatusModel class * @brief The FolderStatusModel class
@ -61,7 +63,6 @@ public:
, _size(0) , _size(0)
, _isExternal(false) , _isExternal(false)
, _fetched(false) , _fetched(false)
, _fetching(false)
, _hasError(false) , _hasError(false)
, _fetchingLabel(false) , _fetchingLabel(false)
, _isUndecided(false) , _isUndecided(false)
@ -77,7 +78,7 @@ public:
bool _isExternal; bool _isExternal;
bool _fetched; // If we did the LSCOL for this folder already bool _fetched; // If we did the LSCOL for this folder already
bool _fetching; // Whether a LSCOL job is currently running QPointer<LsColJob> _fetchingJob; // Currently running LsColJob
bool _hasError; // If the last fetching job ended in an error bool _hasError; // If the last fetching job ended in an error
QString _lastErrorString; QString _lastErrorString;
bool _fetchingLabel; // Whether a 'fetching in progress' label is shown. bool _fetchingLabel; // Whether a 'fetching in progress' label is shown.