Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow an ignored restore #8863

Merged
merged 3 commits into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/unreleased/8837
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Bugfix: Don't crash if a certain move is undone

https://github.com/owncloud/client/issues/8837
2 changes: 1 addition & 1 deletion src/common/remotepermissions.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class OCSYNC_EXPORT RemotePermissions

friend QDebug operator<<(QDebug &dbg, RemotePermissions p)
{
return dbg << p.toString().constData();
return dbg << p.toString();
}
};

Expand Down
12 changes: 12 additions & 0 deletions src/csync/csync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,15 @@

#include "csync.h"
#include "moc_csync.cpp"

#include <QMetaEnum>

QDebug operator<<(QDebug debug, const SyncInstructions &enumValue)
{
static const QMetaObject *mo = qt_getEnumMetaObject(SyncInstruction());
static const int enumIdx = mo->indexOfEnumerator(qt_getEnumName(SyncInstruction()));
static const QMetaEnum me = mo->enumerator(enumIdx);
QDebugStateSaver saver(debug);
debug.nospace().noquote() << me.enumName() << "(" << me.valueToKeys(enumValue) << ")";
return debug;
}
8 changes: 6 additions & 2 deletions src/csync/csync.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Q_ENUM_NS(csync_status_codes_e)
* the csync state of a file.
*/
// clang-format off
enum SyncInstructions {
enum SyncInstruction {
CSYNC_INSTRUCTION_NONE = 0, /* Nothing to do (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_REMOVE = 1 << 1, /* The file need to be removed (RECONCILE) */
CSYNC_INSTRUCTION_RENAME = 1 << 2, /* The file need to be renamed (RECONCILE) */
Expand All @@ -125,7 +125,9 @@ enum SyncInstructions {
CSYNC_INSTRUCTION_EVAL = 1 << 0, // DEPRECATED REMOVED
};
// clang-format on
Q_ENUM_NS(SyncInstructions)
Q_ENUM_NS(SyncInstruction)
Q_DECLARE_FLAGS(SyncInstructions, SyncInstruction)
Q_DECLARE_OPERATORS_FOR_FLAGS(SyncInstructions)

// This enum is used with BITFIELD(3) and BITFIELD(4) in several places.
// Also, this value is stored in the database, so beware of value changes.
Expand Down Expand Up @@ -212,6 +214,8 @@ struct OCSYNC_EXPORT csync_file_stat_s {
{ }
};

OCSYNC_EXPORT QDebug operator<<(QDebug debug, const SyncInstructions &job);

/**
* }@
*/
Expand Down
30 changes: 16 additions & 14 deletions src/libsync/discoveryphase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,34 +158,36 @@ QPair<bool, QByteArray> 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);
}
Expand Down