New discovery: TestSyncEngine::testEmlLocalChecksum
authorOlivier Goffart <ogoffart@woboq.com>
Tue, 10 Jul 2018 09:22:43 +0000 (11:22 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:57:57 +0000 (10:57 +0100)
src/csync/csync_update.cpp
src/libsync/discovery.cpp

index b665249e9ced2f398f93fe3756cc4b2797ce882d..9b96ad454fb2cc934a566930bf779b8985a82a7f 100644 (file)
@@ -274,26 +274,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
               (!_csync_mtime_equal(fs->modtime, base._modtime)
                // zero size in statedb can happen during migration
                || (base._fileSize != 0 && fs->size != base._fileSize))) {
-
-          // Checksum comparison at this stage is only enabled for .eml files,
-          // check #4754 #4755
-          bool isEmlFile = csync_fnmatch("*.eml", fs->path, FNM_CASEFOLD) == 0;
-          if (isEmlFile && fs->size == base._fileSize && !base._checksumHeader.isEmpty()) {
-              if (ctx->callbacks.checksum_hook) {
-                  fs->checksumHeader = ctx->callbacks.checksum_hook(
-                      _rel_to_abs(ctx, fs->path), base._checksumHeader,
-                      ctx->callbacks.checksum_userdata);
-              }
-              bool checksumIdentical = false;
-              if (!fs->checksumHeader.isEmpty()) {
-                  checksumIdentical = fs->checksumHeader == base._checksumHeader;
-              }
-              if (checksumIdentical) {
-                  qCInfo(lcUpdate, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
-                  fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-                  goto out;
-              }
-          }
+          // PORTED: EML
 
           // Preserve the EVAL flag later on if the type has changed.
           if (base._type != fs->type) {
index 4676270836882cad4132e13f67a9c3afb64f8c8f..11cd65115abe2a4e30785568266729b72acfc38f 100644 (file)
@@ -21,6 +21,7 @@
 #include <set>
 #include <QDirIterator>
 #include "vio/csync_vio_local.h"
+#include "common/checksums.h"
 
 namespace OCC {
 
@@ -282,6 +283,7 @@ void ProcessDirectoryJob::processFile(const QString &path,
             item->_instruction = CSYNC_INSTRUCTION_NEW;
             item->_direction = SyncFileItem::Up;
             // TODO! rename;
+            item->_checksumHeader.clear();
             item->_size = localEntry.size;
             item->_modtime = localEntry.modtime;
             item->_type = localEntry.isDirectory ? ItemTypeDirectory : ItemTypeFile;
@@ -289,11 +291,30 @@ void ProcessDirectoryJob::processFile(const QString &path,
         } else {
             item->_instruction = CSYNC_INSTRUCTION_SYNC;
             item->_direction = SyncFileItem::Up;
+            item->_checksumHeader.clear();
             item->_size = localEntry.size;
             item->_modtime = localEntry.modtime;
             item->_previousSize = serverEntry.size;
             item->_previousModtime = serverEntry.modtime;
             _childModified = true;
+
+            // Checksum comparison at this stage is only enabled for .eml files,
+            // check #4754 #4755
+            bool isEmlFile = path.endsWith(QLatin1String(".eml"), Qt::CaseInsensitive);
+            if (isEmlFile && dbEntry._fileSize == localEntry.size && !dbEntry._checksumHeader.isEmpty()) {
+                QByteArray type = parseChecksumHeaderType(dbEntry._checksumHeader);
+                if (!type.isEmpty()) {
+                    // TODO: compute async?
+                    QByteArray checksum = ComputeChecksum::computeNow(_propagator->_localDir + path, type);
+                    if (!checksum.isEmpty()) {
+                        item->_checksumHeader = makeChecksumHeader(type, checksum);
+                        if (item->_checksumHeader == dbEntry._checksumHeader) {
+                            qCDebug(lcDisco) << "NOTE: Checksums are identical, file did not actually change: " << path;
+                            item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
+                        }
+                    }
+                }
+            }
         }
     } else if (!serverModified) {
         item->_instruction = CSYNC_INSTRUCTION_REMOVE;
@@ -311,7 +332,8 @@ void ProcessDirectoryJob::processFile(const QString &path,
         connect(job, &ProcessDirectoryJob::finished, this, &ProcessDirectoryJob::subJobFinished);
         _queuedJobs.push_back(job);
     } else {
-        emit itemDiscovered(item);
+        if (item->_instruction != CSYNC_INSTRUCTION_NONE)
+            emit itemDiscovered(item);
     }
 }