From a19c0764d907e694acf5104130fb0300916edc23 Mon Sep 17 00:00:00 2001 From: Hannah von Reth Date: Wed, 4 Aug 2021 15:07:43 +0200 Subject: [PATCH] Accept all ignored deletes If the local permissions are not correct we perform a prohibited move The move fails with 403 and creates a blacklist entry, but we might get the correct permissions for that file. In the next sync the we don't retry the move as we have the correct permissions now so we want to restore the original file. The original file however is now on the blacklist we mark the restoration as ignore and end up in findAndCancelDeletedJob Fixes: #8837 --- changelog/unreleased/8837 | 3 +++ src/libsync/discoveryphase.cpp | 30 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) create mode 100644 changelog/unreleased/8837 diff --git a/changelog/unreleased/8837 b/changelog/unreleased/8837 new file mode 100644 index 00000000000..3bb14f575f7 --- /dev/null +++ b/changelog/unreleased/8837 @@ -0,0 +1,3 @@ +Bugfix: Don't crash if a certain move is undone + +https://github.com/owncloud/client/issues/8837 diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 0fc34df6ba5..ebc11a03781 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -158,34 +158,36 @@ QPair DiscoveryPhase::findAndCancelDeletedJob(const QString &o QByteArray oldEtag; auto it = _deletedItem.find(originalPath); if (it != _deletedItem.end()) { - const SyncInstructions instruction = (*it)->_instruction; - if (instruction == CSYNC_INSTRUCTION_IGNORE && (*it)->_type == ItemTypeVirtualFile) { + const auto &item = *it; + const SyncInstructions instruction = item->_instruction; + if (instruction == CSYNC_INSTRUCTION_IGNORE && item->_type == ItemTypeVirtualFile) { // re-creation of virtual files count as a delete + // restoration after a prohibited move // a file might be in an error state and thus gets marked as CSYNC_INSTRUCTION_IGNORE // after it was initially marked as CSYNC_INSTRUCTION_REMOVE // return true, to not trigger any additional actions on that file that could elad to dataloss result = true; - oldEtag = (*it)->_etag; + oldEtag = item->_etag; } else { if (!(instruction == CSYNC_INSTRUCTION_REMOVE // re-creation of virtual files count as a delete - || ((*it)->_type == ItemTypeVirtualFile && instruction == CSYNC_INSTRUCTION_NEW) - || ((*it)->_isRestoration && instruction == CSYNC_INSTRUCTION_NEW))) - { + || (item->_type == ItemTypeVirtualFile && instruction == CSYNC_INSTRUCTION_NEW) + || (item->_isRestoration && instruction & (CSYNC_INSTRUCTION_NEW | CSYNC_INSTRUCTION_IGNORE)))) { qCWarning(lcDiscovery) << "OC_ENFORCE(FAILING)" << originalPath; qCWarning(lcDiscovery) << "instruction == CSYNC_INSTRUCTION_REMOVE" << (instruction == CSYNC_INSTRUCTION_REMOVE); - qCWarning(lcDiscovery) << "((*it)->_type == ItemTypeVirtualFile && instruction == CSYNC_INSTRUCTION_NEW)" - << ((*it)->_type == ItemTypeVirtualFile && instruction == CSYNC_INSTRUCTION_NEW); - qCWarning(lcDiscovery) << "((*it)->_isRestoration && instruction == CSYNC_INSTRUCTION_NEW))" - << ((*it)->_isRestoration && instruction == CSYNC_INSTRUCTION_NEW); + qCWarning(lcDiscovery) << "(item->_type == ItemTypeVirtualFile && instruction == CSYNC_INSTRUCTION_NEW)" + << (item->_type == ItemTypeVirtualFile && instruction == CSYNC_INSTRUCTION_NEW); + qCWarning(lcDiscovery) << "(item->_isRestoration && instruction & (CSYNC_INSTRUCTION_NEW | CSYNC_INSTRUCTION_IGNORE)" + << (item->_isRestoration && instruction & (CSYNC_INSTRUCTION_NEW | CSYNC_INSTRUCTION_IGNORE); qCWarning(lcDiscovery) << "instruction" << instruction; - qCWarning(lcDiscovery) << "(*it)->_type" << (*it)->_type; - qCWarning(lcDiscovery) << "(*it)->_isRestoration " << (*it)->_isRestoration; + qCWarning(lcDiscovery) << "item->_type" << item->_type; + qCWarning(lcDiscovery) << "item->_isRestoration " << item->_isRestoration; + qCWarning(lcDiscovery) << "item->_remotePerm" << item->_remotePerm; OC_ENFORCE(false); } - (*it)->_instruction = CSYNC_INSTRUCTION_NONE; + item->_instruction = CSYNC_INSTRUCTION_NONE; result = true; - oldEtag = (*it)->_etag; + oldEtag = item->_etag; } _deletedItem.erase(it); }