From: alex-z Date: Thu, 18 Apr 2024 21:49:47 +0000 (+0200) Subject: Bugfix. Folder case clash conflict. Do not update parent folder record if it contains... X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~7^2~43^2~5 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b24597dfa75276d76b086e9498b75e6205ee1eff;p=nextcloud-desktop.git Bugfix. Folder case clash conflict. Do not update parent folder record if it contains conflicted subfolers. Also fix crash with local rename. Signed-off-by: alex-z --- diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index a4d21a2e3..7016c8d18 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -1291,6 +1291,11 @@ void PropagatorCompositeJob::slotSubJobFinished(SyncFileItem::Status status) auto *subJob = dynamic_cast(sender()); ASSERT(subJob); + if (!_isAnyCaseClashSubFolder) { + if (const auto propagateDirectoryjob = qobject_cast(subJob)) { + _isAnyCaseClashSubFolder = propagateDirectoryjob->_item && propagateDirectoryjob->_item->_isCaseClashFolder; + } + } // Delete the job and remove it from our list of jobs. subJob->deleteLater(); int i = _runningJobs.indexOf(subJob); @@ -1496,15 +1501,16 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status) } } #endif - - const auto result = propagator()->updateMetadata(*_item); - if (!result) { - status = _item->_status = SyncFileItem::FatalError; - _item->_errorString = tr("Error updating metadata: %1").arg(result.error()); - qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file << "with" << result.error(); - } else if (*result == Vfs::ConvertToPlaceholderResult::Locked) { - _item->_status = SyncFileItem::SoftError; - _item->_errorString = tr("File is currently in use"); + if (!_subJobs._isAnyCaseClashSubFolder) { + const auto result = propagator()->updateMetadata(*_item); + if (!result) { + status = _item->_status = SyncFileItem::FatalError; + _item->_errorString = tr("Error updating metadata: %1").arg(result.error()); + qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file << "with" << result.error(); + } else if (*result == Vfs::ConvertToPlaceholderResult::Locked) { + _item->_status = SyncFileItem::SoftError; + _item->_errorString = tr("File is currently in use"); + } } } } diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index 0e4640e22..5c5efa5cf 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -246,6 +246,7 @@ public: QVector _runningJobs; SyncFileItem::Status _hasError = SyncFileItem::NoStatus; // NoStatus, or NormalError / SoftError if there was an error quint64 _abortsCount = 0; + bool _isAnyCaseClashSubFolder = false; explicit PropagatorCompositeJob(OwncloudPropagator *propagator) : PropagatorJob(propagator) diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index 21390cb08..4c40b6827 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -183,6 +183,7 @@ void PropagateLocalMkdir::startLocalMkdir() } if (Utility::fsCasePreserving() && propagator()->localFileNameClash(_item->_file)) { + _item->_isCaseClashFolder = true; qCWarning(lcPropagateLocalMkdir) << "New folder to create locally already exists with different case:" << _item->_file; done(SyncFileItem::FileNameClash, tr("Folder %1 cannot be created because of a local file or folder name clash!").arg(newDirStr), ErrorCategory::GenericError); return; @@ -302,7 +303,17 @@ void PropagateLocalRename::start() if (QString::compare(_item->_file, _item->_renameTarget, Qt::CaseInsensitive) != 0 && propagator()->localFileNameClash(_item->_renameTarget)) { - qCInfo(lcPropagateLocalRename) << "renaming a case clashed file" << _item->_file << _item->_renameTarget; + qCInfo(lcPropagateLocalRename) << "renaming a case clashed item" << _item->_file << _item->_renameTarget; + if (_item->isDirectory()) { + // #HotFix + // fix a crash (we can not create a conflicted copy for folders) + // right now, the conflict resolution will not even work for this scenario with folders, + // but, let's fix it step by step, this will be a second stage + done(SyncFileItem::FileNameClash, + tr("Folder %1 cannot be renamed because of a local file or folder name clash!").arg(_item->_file), + ErrorCategory::GenericError); + return; + } const auto caseClashConflictResult = propagator()->createCaseClashConflict(_item, existingFile); if (caseClashConflictResult) { done(SyncFileItem::SoftError, *caseClashConflictResult, ErrorCategory::GenericError); diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h index d06e6f6d9..de01c1c4d 100644 --- a/src/libsync/syncfileitem.h +++ b/src/libsync/syncfileitem.h @@ -335,6 +335,8 @@ public: bool _isFileDropDetected = false; bool _isEncryptedMetadataNeedUpdate = false; + + bool _isCaseClashFolder = false; }; inline bool operator<(const SyncFileItemPtr &item1, const SyncFileItemPtr &item2)