]> dgit.raspbian.org Git - nextcloud-desktop.git/commitdiff
Update file's metadata in the local database when the etag changes while file remains...
authoralex-z <blackslayer4@gmail.com>
Tue, 20 Dec 2022 18:49:35 +0000 (19:49 +0100)
committerallexzander <allexzander@users.noreply.github.com>
Fri, 30 Dec 2022 15:57:32 +0000 (16:57 +0100)
Signed-off-by: alex-z <blackslayer4@gmail.com>
src/libsync/propagatedownload.cpp
src/libsync/propagatedownload.h
test/testsyncconflict.cpp

index b390cee5585f145d244ab9228dd69195460b4795..2a0981410920eb647f68a02bd6a09cb9d468bc26 100644 (file)
@@ -1106,13 +1106,39 @@ void PropagateDownloadFile::contentChecksumComputed(const QByteArray &checksumTy
 {
     _item->_checksumHeader = makeChecksumHeader(checksumType, checksum);
 
+    const auto localFilePath = propagator()->fullLocalPath(_item->_file);
+    SyncJournalFileRecord record;
+    if (_item->_instruction != CSYNC_INSTRUCTION_CONFLICT && FileSystem::fileExists(localFilePath)
+        && (propagator()->_journal->getFileRecord(_item->_file, &record) && record.isValid())
+        && (record._modtime == _item->_modtime && record._etag != _item->_etag)) {
+        const auto computeChecksum = new ComputeChecksum(this);
+        computeChecksum->setChecksumType(checksumType);
+        connect(computeChecksum, &ComputeChecksum::done, this, &PropagateDownloadFile::localFileContentChecksumComputed);
+        computeChecksum->start(localFilePath);
+        return;
+    }
+
+    finalizeDownload();
+}
+
+void PropagateDownloadFile::localFileContentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
+{
+    if (_item->_checksumHeader == makeChecksumHeader(checksumType, checksum)) {
+        FileSystem::remove(_tmpFile.fileName());
+        updateMetadata(false);
+        return;
+    }
+    finalizeDownload();
+}
+
+void PropagateDownloadFile::finalizeDownload()
+{
     if (_isEncrypted) {
         if (_downloadEncryptedHelper->decryptFile(_tmpFile)) {
-          downloadFinished();
+            downloadFinished();
         } else {
-          done(SyncFileItem::NormalError, _downloadEncryptedHelper->errorString());
+            done(SyncFileItem::NormalError, _downloadEncryptedHelper->errorString());
         }
-
     } else {
         downloadFinished();
     }
index 47d8a5c9e74339191486e207c757531a74885697..cb9304d3e709c6adadfee45754b67c1bd13eb0ff 100644 (file)
@@ -230,6 +230,10 @@ private slots:
     void transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum);
     /// Called when the download's checksum computation is done
     void contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum);
+    /// Called when the local file's checksum computation is done
+    void localFileContentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum);
+
+    void finalizeDownload();
     void downloadFinished();
     /// Called when it's time to update the db metadata
     void updateMetadata(bool isConflict);
index a12b47645610a2e756b6b048047d0e289946a42d..8a00d76fec5a6d27ebc0ee981c5ac004be0fc60b 100644 (file)
@@ -599,6 +599,42 @@ private slots:
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
     }
 
+    void testEtagChangeFileNotChangedGeneratesNoConflicts()
+    {
+        FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
+        ItemCompletedSpy completeSpy(fakeFolder);
+
+        fakeFolder.remoteModifier().insert("A/fake_conflict", 'W');
+        QVERIFY(fakeFolder.syncOnce());
+        QVERIFY(!itemConflict(completeSpy, "A/fake_conflict"));
+
+        completeSpy.clear();
+
+        fakeFolder.remoteModifier().setContents("A/fake_conflict", 'W');
+        fakeFolder.localModifier().setContents("A/fake_conflict", 'W');
+
+        QVERIFY(fakeFolder.syncOnce());
+        QVERIFY(!itemConflict(completeSpy, "A/fake_conflict"));
+    }
+
+    void testEtagChangeFileChangedGeneratesConflicts()
+    {
+        FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
+        ItemCompletedSpy completeSpy(fakeFolder);
+
+        fakeFolder.remoteModifier().insert("A/real_conflict", 'W');
+        QVERIFY(fakeFolder.syncOnce());
+        QVERIFY(!itemConflict(completeSpy, "A/real_conflict"));
+
+        completeSpy.clear();
+
+        fakeFolder.remoteModifier().setContents("A/real_conflict", 'W');
+        fakeFolder.localModifier().setContents("A/real_conflict", 'L');
+
+        QVERIFY(fakeFolder.syncOnce());
+        QVERIFY(itemConflict(completeSpy, "A/real_conflict"));
+    }
+
     // Test what happens if we remove entries both on the server, and locally
     void testRemoveRemove()
     {