VFS + E2EE placeholder size migration from old versions.
authorallexzander <blackslayer4@gmail.com>
Tue, 13 Jul 2021 12:19:04 +0000 (15:19 +0300)
committerallexzander (Rebase PR Action) <allexzander@users.noreply.github.com>
Fri, 20 Aug 2021 12:57:22 +0000 (12:57 +0000)
Signed-off-by: allexzander <blackslayer4@gmail.com>
src/libsync/discovery.cpp
src/libsync/discoveryphase.cpp
src/libsync/discoveryphase.h

index a20697336393094bfd853eea13715db6c5d8c564..8252c82fc1c8221e7b4d259bf2cc1b4244fc71eb 100644 (file)
@@ -462,11 +462,14 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
     if (dbEntry.isValid()) {
         qint64 size = serverEntry.size;
 
+        bool metaDataSizeNeedsUpdateForE2EEFile = false;
+
         if (dbEntry.isVirtualFile() && (!item->_encryptedFileName.isEmpty()) && size > 0) {
             // make sure we set correct size when file was downloaded previously and has now been changed on the server
             // serverEntry always includes extra CommonConstants::e2EeTagSize bytes for e2e encrypted files
             // we don't need those neither when creating a placeholder nor when storing hydrated file on disk
             size = serverEntry.size - CommonConstants::e2EeTagSize;
+            metaDataSizeNeedsUpdateForE2EEFile = dbEntry._fileSize == serverEntry.size;
         }
 
         if (serverEntry.isDirectory != dbEntry.isDirectory()) {
@@ -496,14 +499,32 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
             } else {
                 item->_instruction = CSYNC_INSTRUCTION_SYNC;
             }
-        } else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId) {
+        } else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId || metaDataSizeNeedsUpdateForE2EEFile) {
+            if (metaDataSizeNeedsUpdateForE2EEFile) {
+                item->_size = serverEntry.size - CommonConstants::e2EeTagSize;
+            }
             item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
             item->_direction = SyncFileItem::Down;
         } else {
             // if (is virtual mode enabled and folder is encrypted - check if the size is the same as on the server and then - trigger server query
             // to update a placeholder with corrected size (-16 Bytes)
             // or, maybe, add a flag to the database - vfsE2eeSizeCorrected? if it is not set - subtract it from the placeholder's size and re-create/update a placeholder?
-            processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, ParentNotChanged);
+            QueryMode serverQueryMode = ParentNotChanged;
+            if (dbEntry.isDirectory() && dbEntry._isE2eEncrypted) {
+                qint64 totalSizeOfPath = 0;
+                if (_discoveryData->_statedb->listFilesInPath(dbEntry.path().toUtf8(), [this, &totalSizeOfPath](const OCC::SyncJournalFileRecord &record) {
+                        if (record.isFile()) {
+                            totalSizeOfPath += record._fileSize + CommonConstants::e2EeTagSize;
+                        } else if (record.isVirtualFile()) {
+                            totalSizeOfPath += record._fileSize;
+                        }
+                    })) {
+                    if (totalSizeOfPath != 0 && totalSizeOfPath == serverEntry.sizeOfFolder) {
+                        serverQueryMode = NormalQuery;
+                    }
+                }
+            }
+            processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, serverQueryMode);
             return;
         }
 
index 6a7837708b2bcc0ae29e84a82ce774294406dc0e..6b108e4ddb1fa792dc4bf3e917aabea433166299 100644 (file)
@@ -349,6 +349,7 @@ void DiscoverySingleDirectoryJob::start()
           << "getlastmodified"
           << "getcontentlength"
           << "getetag"
+          << "http://owncloud.org/ns:size"
           << "http://owncloud.org/ns:id"
           << "http://owncloud.org/ns:downloadURL"
           << "http://owncloud.org/ns:dDC"
@@ -429,6 +430,10 @@ static void propertyMapToRemoteInfo(const QMap<QString, QString> &map, RemoteInf
             result.isE2eEncrypted = true;
         }
     }
+
+    if (result.isDirectory && map.contains("size")) {
+        result.sizeOfFolder = map.value("size").toInt();
+    }
 }
 
 void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &file, const QMap<QString, QString> &map)
@@ -455,6 +460,9 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi
             _isE2eEncrypted = true;
             Q_ASSERT(!_fileId.isEmpty());
         }
+        if (map.contains("size")) {
+            _size = map.value("size").toInt();
+        }
     } else {
 
         RemoteInfo result;
index 9868e3ec66c10cb4f2da910eccddf3abc6729011..26b06e15f1041c05d085d78a6e8ab44d4743af11 100644 (file)
@@ -55,6 +55,7 @@ struct RemoteInfo
     OCC::RemotePermissions remotePerm;
     time_t modtime = 0;
     int64_t size = 0;
+    int64_t sizeOfFolder = 0;
     bool isDirectory = false;
     bool isE2eEncrypted = false;
     QString e2eMangledName;
@@ -153,6 +154,7 @@ private:
     // If this directory is e2ee
     bool _isE2eEncrypted;
     // If set, the discovery will finish with an error
+    int64_t _size = 0;
     QString _error;
     QPointer<LsColJob> _lsColJob;