vfs suffix: Ignore server files or synced files with the suffix #6953

This commit is contained in:
Christian Kamm 2019-01-10 13:26:26 +01:00 committed by Kevin Ottens
parent e774c6c739
commit 836d298141
No known key found for this signature in database
GPG key ID: 074BBBCB8DECC9E2
2 changed files with 76 additions and 18 deletions

View file

@ -82,21 +82,6 @@ void ProcessDirectoryJob::process()
}
_serverNormalQueryEntries.clear();
for (auto &e : _localNormalQueryEntries) {
// Remove the virtual file suffix
auto name = e.name;
if (e.isVirtualFile && isVfsWithSuffix()) {
chopVirtualFileSuffix(name);
auto &entry = entries[name];
// If there is both a virtual file and a real file, we must keep the real file
if (!entry.localEntry.isValid())
entry.localEntry = std::move(e);
} else {
entries[name].localEntry = std::move(e);
}
}
_localNormalQueryEntries.clear();
// fetch all the name from the DB
auto pathU8 = _currentFolder._original.toUtf8();
if (!_discoveryData->_statedb->listFilesInPath(pathU8, [&](const SyncJournalFileRecord &rec) {
@ -109,6 +94,21 @@ void ProcessDirectoryJob::process()
return;
}
for (auto &e : _localNormalQueryEntries) {
// Normally for vfs-suffix files the local entries need the suffix removed.
// However, don't do it if "foo.owncloud" exists on the server or in the db
// (as a non-virtual file): we don't want to create two entries.
auto name = e.name;
if (e.isVirtualFile && isVfsWithSuffix() && entries.find(name) == entries.end()) {
chopVirtualFileSuffix(name);
// If there is both a virtual file and a real file, we must keep the real file
if (entries[name].localEntry.isValid())
continue;
}
entries[name].localEntry = std::move(e);
}
_localNormalQueryEntries.clear();
//
// Iterate over entries and process them
//
@ -123,7 +123,7 @@ void ProcessDirectoryJob::process()
if (e.dbEntry.isVirtualFile()) {
ASSERT(hasVirtualFileSuffix(e.dbEntry._path));
addVirtualFileSuffix(path._original);
} else if (e.localEntry.isVirtualFile) {
} else if (e.localEntry.isVirtualFile && !e.dbEntry.isValid()) {
// We don't have a db entry - but it should be at this path
addVirtualFileSuffix(path._original);
}
@ -303,6 +303,18 @@ void ProcessDirectoryJob::processFile(PathTuple path,
if (item->_type == ItemTypeVirtualFileDehydration)
item->_type = ItemTypeFile;
// VFS suffixed files on the server are ignored
if (isVfsWithSuffix()) {
if (hasVirtualFileSuffix(serverEntry.name)
|| (localEntry.isVirtualFile && !dbEntry.isVirtualFile() && hasVirtualFileSuffix(dbEntry._path))) {
item->_instruction = CSYNC_INSTRUCTION_IGNORE;
item->_errorString = tr("File has extension reserved for virtual files.");
_childIgnored = true;
emit _discoveryData->itemDiscovered(item);
return;
}
}
if (serverEntry.isValid()) {
processFileAnalyzeRemoteInfo(item, path, localEntry, serverEntry, dbEntry);
return;
@ -681,6 +693,9 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
item->_direction = SyncFileItem::Down;
item->_instruction = CSYNC_INSTRUCTION_NEW;
item->_type = ItemTypeVirtualFile;
} else {
qCInfo(lcDisco) << "Virtual file with non-virtual db entry, ignoring:" << item->_file;
item->_instruction = CSYNC_INSTRUCTION_IGNORE;
}
}
} else if (!typeChange && ((dbEntry._modtime == localEntry.modtime && dbEntry._fileSize == localEntry.size) || localEntry.isDirectory)) {

View file

@ -742,8 +742,7 @@ private slots:
void testNewVirtuals()
{
FakeFolder fakeFolder{ FileInfo() };
SyncOptions syncOptions = vfsSyncOptions(fakeFolder);
fakeFolder.syncEngine().setSyncOptions(syncOptions);
fakeFolder.syncEngine().setSyncOptions(vfsSyncOptions(fakeFolder));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
auto setPin = [&] (const QByteArray &path, PinState state) {
@ -791,6 +790,50 @@ private slots:
QVERIFY(fakeFolder.currentLocalState().find("local/file1"));
QVERIFY(fakeFolder.currentLocalState().find("unspec/file1.nextcloud"));
}
// Check what happens if vfs-suffixed files exist on the server or in the db
void testSuffixOnServerOrDb()
{
FakeFolder fakeFolder{ FileInfo() };
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &)));
auto cleanup = [&]() {
completeSpy.clear();
};
cleanup();
// file1.nextcloud is happily synced with Vfs::Off
fakeFolder.remoteModifier().mkdir("A");
fakeFolder.remoteModifier().insert("A/file1.nextcloud");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
cleanup();
// Enable suffix vfs
fakeFolder.syncEngine().setSyncOptions(vfsSyncOptions(fakeFolder));
// Local changes of suffixed file do nothing
fakeFolder.localModifier().appendByte("A/file1.nextcloud");
QVERIFY(fakeFolder.syncOnce());
QVERIFY(itemInstruction(completeSpy, "A/file1.nextcloud", CSYNC_INSTRUCTION_IGNORE));
cleanup();
// Remote don't do anything either
fakeFolder.remoteModifier().appendByte("A/file1.nextcloud");
QVERIFY(fakeFolder.syncOnce());
QVERIFY(itemInstruction(completeSpy, "A/file1.nextcloud", CSYNC_INSTRUCTION_IGNORE));
cleanup();
// New files with a suffix aren't propagated downwards in the first place
fakeFolder.remoteModifier().insert("A/file2.nextcloud");
QVERIFY(fakeFolder.syncOnce());
QVERIFY(itemInstruction(completeSpy, "A/file2.nextcloud", CSYNC_INSTRUCTION_IGNORE));
QVERIFY(fakeFolder.currentRemoteState().find("A/file2.nextcloud"));
QVERIFY(!fakeFolder.currentLocalState().find("A/file2"));
QVERIFY(!fakeFolder.currentLocalState().find("A/file2.nextcloud"));
QVERIFY(!fakeFolder.currentLocalState().find("A/file2.nextcloud.nextcloud"));
cleanup();
}
};
QTEST_GUILESS_MAIN(TestSyncVirtualFiles)