marinofaggiana 4 years ago
parent
commit
3615fa7d17

+ 1 - 1
Cartfile

@@ -4,7 +4,7 @@ github "kishikawakatsumi/UICKeyChainStore" "v2.1.2"
 github "MortimerGoro/MGSwipeTableCell" "1.6.8"
 github "dzenbot/DZNEmptyDataSet" "v1.8.1"
 github "jdg/MBProgressHUD" "1.1.0"
-github "realm/realm-cocoa" "v5.3.4"
+github "realm/realm-cocoa" "v5.3.5"
 github "SVGKit/SVGKit" "3.x"
 github "WeTransfer/WeScan" "1.2.0"
 github "malcommac/SwiftRichString"

+ 1 - 1
Cartfile.resolved

@@ -19,7 +19,7 @@ github "malcommac/SwiftRichString" "3.7.2"
 github "marinofaggiana/KTVHTTPCache" "2.0.2"
 github "marinofaggiana/TOPasscodeViewController" "0.0.7"
 github "nextcloud/ios-communication-library" "v0.77"
-github "realm/realm-cocoa" "v5.3.4"
+github "realm/realm-cocoa" "v5.3.5"
 github "rechsteiner/Parchment" "v2.4.0"
 github "scenee/FloatingPanel" "v1.7.5"
 github "tilltue/TLPhotoPicker" "2.0.12"

+ 31 - 0
Carthage/Checkouts/realm-cocoa/CHANGELOG.md

@@ -1,3 +1,34 @@
+5.3.5 Release notes (2020-08-20)
+=============================================================
+
+### Fixed
+
+* Opening Realms on background threads could produce spurious Incorrect Thread
+  exceptions when a cached Realm existed for a previously existing thread with
+  the same thread ID as the current thread.
+  ([#6659](https://github.com/realm/realm-cocoa/issues/6659),
+  [#6689](https://github.com/realm/realm-cocoa/issues/6689),
+  [#6712](https://github.com/realm/realm-cocoa/issues/6712), since 5.0.0).
+* Upgrading a table with incoming links but no properties would crash. This was
+  probably not possible to hit in practice as we reject object types with no
+  properties.
+* Upgrading a non-nullable List which nonetheless contained null values would
+  crash. This was possible due to missing error-checking in some older versions
+  of Realm.
+
+### Compatibility
+
+* File format: Generates Realms with format v10 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Realm Studio: 3.11 or later.
+* APIs are backwards compatible with all previous releases in the 5.x.y series.
+* Carthage release for Swift is built with Xcode 11.6.
+
+### Internal
+
+* Upgraded realm-core from v6.0.18 to v6.0.19
+* Upgraded realm-sync from v5.0.15 to v5.0.16
+
 5.3.4 Release notes (2020-08-17)
 =============================================================
 

+ 3 - 5
Carthage/Checkouts/realm-cocoa/Configuration/Base.xcconfig

@@ -46,13 +46,11 @@ GCC_WARN_UNUSED_VARIABLE = YES;
 SWIFT_COMPILATION_MODE = wholemodule;
 SWIFT_OPTIMIZATION_LEVEL = -Owholemodule;
 WARNING_CFLAGS = -Wmismatched-tags -Wunused-private-field -Wpartial-availability;
-OTHER_CFLAGS = -fvisibility-inlines-hidden $(REALM_CATALYST_FLAGS);
-OTHER_CFLAGS[arch=armv7] = -fvisibility-inlines-hidden -fno-aligned-new $(REALM_CATALYST_FLAGS);
-OTHER_LDFLAGS = $(REALM_CATALYST_FLAGS);
-OTHER_SWIFT_FLAGS = $(REALM_CATALYST_FLAGS);
+OTHER_CFLAGS = -fvisibility-inlines-hidden;
+OTHER_CFLAGS[arch=armv7] = -fvisibility-inlines-hidden -fno-aligned-new;
 
-OTHER_CPLUSPLUSFLAGS = $(inherited) -isystem core/include;
 HEADER_SEARCH_PATHS = $(inherited) Realm/ObjectStore/src;
+REALM_CORE_FRAMEWORK = core/realm-sync$(REALM_LIBRARY_SUFFIX).xcframework;
 
 CODE_SIGN_IDENTITY[sdk=iphone*] = iPhone Developer;
 CODE_SIGNING_REQUIRED[sdk=macosx] = NO;

+ 0 - 14
Carthage/Checkouts/realm-cocoa/Configuration/Realm/Realm.xcconfig

@@ -17,7 +17,6 @@ FRAMEWORK_VERSION = A;
 
 APPLICATION_EXTENSION_API_ONLY = YES;
 HEADER_SEARCH_PATHS = $(inherited) $(DERIVED_FILE_DIR);
-LIBRARY_SEARCH_PATHS = core;
 
 ENABLE_BITCODE[sdk=iphone*] = YES;
 ENABLE_BITCODE[sdk=watch*] = YES;
@@ -27,16 +26,3 @@ LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Framewor
 LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
 LD_RUNPATH_SEARCH_PATHS[sdk=watch*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
 LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
-
-REALM_PLATFORM_SUFFIX_ = $(PLATFORM_NAME); // Xcode 10 does not define SDK_VARIANT
-REALM_PLATFORM_SUFFIX_macos = macosx;
-REALM_PLATFORM_SUFFIX_iosmac = maccatalyst;
-REALM_PLATFORM_SUFFIX = $(REALM_PLATFORM_SUFFIX_$(SDK_VARIANT));
-OTHER_LDFLAGS[sdk=macosx*] = -lrealm-$(REALM_PLATFORM_SUFFIX)$(REALM_LIBRARY_SUFFIX) $(REALM_CATALYST_FLAGS);
-OTHER_LIBTOOLFLAGS[sdk=macosx*] = -lrealm-$(REALM_PLATFORM_SUFFIX)$(REALM_LIBRARY_SUFFIX);
-OTHER_LDFLAGS[sdk=iphone*] = -lrealm-ios$(REALM_LIBRARY_SUFFIX);
-OTHER_LIBTOOLFLAGS[sdk=iphone*] = -lrealm-ios$(REALM_LIBRARY_SUFFIX);
-OTHER_LDFLAGS[sdk=watch*] = -lrealm-watchos$(REALM_LIBRARY_SUFFIX);
-OTHER_LIBTOOLFLAGS[sdk=watch*] = -lrealm-watchos$(REALM_LIBRARY_SUFFIX);
-OTHER_LDFLAGS[sdk=appletv*] = -lrealm-tvos$(REALM_LIBRARY_SUFFIX);
-OTHER_LIBTOOLFLAGS[sdk=appletv*] = -lrealm-tvos$(REALM_LIBRARY_SUFFIX);

+ 12 - 1
Carthage/Checkouts/realm-cocoa/Realm/RLMRealmUtil.mm

@@ -28,6 +28,7 @@
 
 #import "binding_context.hpp"
 #import "shared_realm.hpp"
+#import "util/scheduler.hpp"
 
 #import <map>
 #import <mutex>
@@ -54,7 +55,17 @@ RLMRealm *RLMGetAnyCachedRealmForPath(std::string const& path) {
 
 RLMRealm *RLMGetThreadLocalCachedRealmForPath(std::string const& path, void *key) {
     std::lock_guard<std::mutex> lock(s_realmCacheMutex);
-    return [s_realmsPerPath[path] objectForKey:(__bridge id)key];
+    RLMRealm *realm = [s_realmsPerPath[path] objectForKey:(__bridge id)key];
+    if (realm && !realm->_realm->scheduler()->is_on_thread()) {
+        // We can get here in two cases: if the user is trying to open a
+        // queue-bound Realm from the wrong queue, or if we have a stale cached
+        // Realm which is bound to a thread that no longer exists. In the first
+        // case we'll throw an error later on; in the second we'll just create
+        // a new RLMRealm and replace the cache entry with one bound to the
+        // thread that now exists.
+        realm = nil;
+    }
+    return realm;
 }
 
 void RLMClearRealmCache() {

+ 2 - 2
Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist

@@ -17,11 +17,11 @@
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
-	<string>5.3.4</string>
+	<string>5.3.5</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>5.3.4</string>
+	<string>5.3.5</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>Copyright © 2014 Realm. All rights reserved.</string>
 	<key>NSPrincipalClass</key>

+ 37 - 2
Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm

@@ -29,6 +29,7 @@
 #import <mach/vm_map.h>
 #import <sys/resource.h>
 #import <thread>
+#import <unordered_set>
 
 #import <realm/util/file.hpp>
 #import <realm/db_options.hpp>
@@ -1561,17 +1562,31 @@
         @autoreleasepool {
             RLMRealm *backgroundThreadRealm = [RLMRealm defaultRealm];
             RLMRealm *q1Realm3 = [RLMRealm defaultRealmForQueue:q1];
-            RLMRealm *q2Realm3 = [RLMRealm defaultRealmForQueue:q2];
+            XCTAssertThrows([RLMRealm defaultRealmForQueue:q2]);
 
             XCTAssertNotEqual(backgroundThreadRealm, mainThreadRealm1);
             XCTAssertNotEqual(backgroundThreadRealm, mainQueueRealm1);
             XCTAssertNotEqual(backgroundThreadRealm, q1Realm1);
             XCTAssertNotEqual(backgroundThreadRealm, q1Realm2);
             XCTAssertEqual(q1Realm1, q1Realm3);
-            XCTAssertEqual(q2Realm2, q2Realm3);
         }
     });
     dispatch_sync(q1, ^{});
+
+    dispatch_async(q2, ^{
+        @autoreleasepool {
+            RLMRealm *backgroundThreadRealm = [RLMRealm defaultRealm];
+            XCTAssertThrows([RLMRealm defaultRealmForQueue:q1]);
+            RLMRealm *q2Realm3 = [RLMRealm defaultRealmForQueue:q2];
+
+            XCTAssertNotEqual(backgroundThreadRealm, mainThreadRealm1);
+            XCTAssertNotEqual(backgroundThreadRealm, mainQueueRealm1);
+            XCTAssertNotEqual(backgroundThreadRealm, q1Realm1);
+            XCTAssertNotEqual(backgroundThreadRealm, q1Realm2);
+            XCTAssertEqual(q2Realm2, q2Realm3);
+        }
+    });
+    dispatch_sync(q2, ^{});
 }
 
 - (void)testQueueValidation {
@@ -2085,6 +2100,26 @@
     [self waitForExpectationsWithTimeout:1 handler:nil];
 }
 
+- (void)testThreadIDReuse {
+    // Open Realms on new threads until we get repeated thread IDs, while
+    // retaining each Realm opened. This verifies that we don't get a Realm from
+    // an old thread that no longer exists from the cache.
+    NSMutableArray *realms = [NSMutableArray array];
+    std::unordered_set<pthread_t> threadIds;
+    bool done = false;
+    while (!done) {
+        std::thread([&] {
+            RLMRealm *realm = [RLMRealm defaultRealm];
+            [realms addObject:realm];
+            (void)[IntObject allObjectsInRealm:realm].count;
+            [realm refresh];
+            if (!threadIds.insert(pthread_self()).second) {
+                done = true;
+            }
+        }).join();
+    }
+}
+
 - (void)testAuxiliaryFilesAreExcludedFromBackup {
     RLMSetSkipBackupAttribute(true);
     @autoreleasepool { [RLMRealm defaultRealm]; }

+ 69 - 90
Carthage/Checkouts/realm-cocoa/build.sh

@@ -316,29 +316,72 @@ fi
 # Downloading
 ######################################
 
+copy_core() {
+    local src="$1"
+    if [ -d .git ]; then
+        git clean -xfdq core
+    else
+        rm -r core
+        mkdir core
+    fi
+    ditto "$src" core
+}
+
 download_common() {
-    local download_type=$1 tries_left=3 version url error temp_dir temp_path tar_path
+    local download_type="$1" tries_left=3 version url error kind suffix
+
+    if [ "$2" = xcframework ]; then
+        kind='-xcframework'
+        suffix='-xcframework'
+    else
+        kind='-cocoa'
+        suffix=''
+    fi
 
     if [ "$download_type" == "core" ]; then
         version=$REALM_CORE_VERSION
-        url="${REALM_BASE_URL}/core/realm-core-${version}.tar.xz"
+        url="${REALM_BASE_URL}/core/realm-core${kind}-${version}.tar.xz"
     elif [ "$download_type" == "sync" ]; then
         version=$REALM_SYNC_VERSION
-        url="${REALM_BASE_URL}/sync/realm-sync-cocoa-${version}.tar.xz"
+        url="${REALM_BASE_URL}/sync/realm-sync${kind}-${version}.tar.xz"
     else
         echo "Unknown dowload_type: $download_type"
         exit 1
     fi
 
+    # First check if we need to do anything
+    if [ -e core/version.txt ]; then
+        if [ "$(cat core/version.txt)" == "$version" ]; then
+            echo "Version ${version} already present"
+            exit 0
+        else
+            echo "Switching from version $(cat core/version.txt) to ${version}"
+        fi
+    else
+        if [ "$(find core -name librealm.a)" ]; then
+            echo 'Using existing custom core build without checking version'
+            exit 0
+        fi
+    fi
+
+    # We may already have this version downloaded and just need to set it as
+    # the active one
+    local versioned_dir="${download_type}-${version}${suffix}"
+    if [ -e "$versioned_dir/version.txt" ]; then
+        echo "Setting ${version} as the active version"
+        copy_core "$versioned_dir${suffix}"
+        exit 0
+    fi
+
     echo "Downloading dependency: ${download_type} ${version} from ${url}"
 
     if [ -z "$TMPDIR" ]; then
         TMPDIR='/tmp'
     fi
-    temp_dir=$(dirname "$TMPDIR/waste")/${download_type}_bin
+    local temp_dir=$(dirname "$TMPDIR/waste")/realm-${download_type}-tmp
     mkdir -p "$temp_dir"
-    tar_path="${temp_dir}/${download_type}-${version}.tar.xz"
-    temp_path="${tar_path}.tmp"
+    local tar_path="${temp_dir}/${versioned_dir}.tar.xz"
+    local temp_path="${tar_path}.tmp"
 
     while [ 0 -lt $tries_left ] && [ ! -f "$tar_path" ]; do
         if ! error=$(/usr/bin/curl --fail --silent --show-error --location "$url" --output "$temp_path" 2>&1); then
@@ -357,20 +400,15 @@ download_common() {
         cd "$temp_dir"
         rm -rf "$download_type"
         tar xf "$tar_path" --xz
-        mv core "${download_type}-${version}"
+        if [ ! -f core/version.txt ]; then
+            printf %s "${version}" > core/version.txt
+        fi
+        mv core "${versioned_dir}"
     )
 
-    rm -rf "${download_type}-${version}" core
-    mv "${temp_dir}/${download_type}-${version}" .
-    ln -s "${download_type}-${version}" core
-}
-
-download_core() {
-    download_common "core"
-}
-
-download_sync() {
-    download_common "sync"
+    rm -rf "${versioned_dir}"
+    mv "${temp_dir}/${versioned_dir}" .
+    copy_core "$versioned_dir"
 }
 
 ######################################
@@ -412,31 +450,7 @@ case "$COMMAND" in
     # Core
     ######################################
     "download-core")
-        if [ "$REALM_CORE_VERSION" = "current" ]; then
-            echo "Using version of core already in core/ directory"
-            exit 0
-        fi
-        if [ -d core -a -d ../realm-core -a ! -L core ]; then
-          # Allow newer versions than expected for local builds as testing
-          # with unreleased versions is one of the reasons to use a local build
-          if ! $(grep -i "${REALM_CORE_VERSION} Release notes" core/release_notes.txt >/dev/null); then
-              echo "Local build of core is out of date."
-              exit 1
-          else
-              echo "The core library seems to be up to date."
-          fi
-        elif ! [ -L core ]; then
-            echo "core is not a symlink. Deleting..."
-            rm -rf core
-            download_core
-        # With a prebuilt version we only want to check the first non-empty
-        # line so that checking out an older commit will download the
-        # appropriate version of core if the already-present version is too new
-        elif ! $(grep -m 1 . core/release_notes.txt | grep -i "${REALM_CORE_VERSION} RELEASE NOTES" >/dev/null); then
-            download_core
-        else
-            echo "The core library seems to be up to date."
-        fi
+        download_common "core" "$2"
         exit 0
         ;;
 
@@ -444,21 +458,7 @@ case "$COMMAND" in
     # Sync
     ######################################
     "download-sync")
-        if [ "$REALM_SYNC_VERSION" = "current" ]; then
-            echo "Using version of core already in core/ directory"
-            exit 0
-        fi
-        if [ -d core -a -d ../realm-core -a -d ../realm-sync -a ! -L core ]; then
-          echo "Using version of core already in core/ directory"
-        elif ! [ -L core ]; then
-            echo "core is not a symlink. Deleting..."
-            rm -rf core
-            download_sync
-        elif [[ "$(cat core/version.txt)" != "$REALM_SYNC_VERSION" ]]; then
-            download_sync
-        else
-            echo "The core library seems to be up to date."
-        fi
+        download_common "sync" "$2"
         exit 0
         ;;
 
@@ -551,32 +551,23 @@ case "$COMMAND" in
         xc "-scheme 'RealmSwift' -configuration $CONFIGURATION build"
         destination="build/osx/swift-$REALM_XCODE_VERSION"
         clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework"
-        rm -rf "$destination/Realm.framework"
-        cp -R build/osx/Realm.framework "$destination"
+        clean_retrieve "build/osx/Realm.framework" "$destination" "Realm.framework"
         exit 0
         ;;
 
     "catalyst")
-        xc "-scheme Realm -configuration $CONFIGURATION \
-            REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' \
-            REALM_PLATFORM_SUFFIX='maccatalyst' \
-            IS_MACCATALYST=YES"
-        clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/Realm.framework" "build/catalyst" "Realm.framework"
+        export REALM_SDKROOT=iphoneos
+        xc "-scheme Realm -configuration $CONFIGURATION -destination variant='Mac Catalyst'"
+        clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION-maccatalyst/Realm.framework" "build/catalyst" "Realm.framework"
         ;;
 
     "catalyst-swift")
         sh build.sh catalyst
-        # FIXME: change this to just "-destination variant='Mac Catalyst'" once the CI machines are running 10.15
-        xc "-scheme 'RealmSwift' -configuration $CONFIGURATION build \
-            REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' \
-            REALM_PLATFORM_SUFFIX='maccatalyst' \
-            SWIFT_DEPLOYMENT_TARGET='13.0-macabi' \
-            SWIFT_PLATFORM_TARGET_PREFIX='ios' \
-            IS_MACCATALYST=YES"
+        export REALM_SDKROOT=iphoneos
+        xc "-scheme 'RealmSwift' -configuration $CONFIGURATION -destination variant='Mac Catalyst' build"
         destination="build/catalyst/swift-$REALM_XCODE_VERSION"
-        clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework"
-        rm -rf "$destination/Realm.framework"
-        cp -R build/catalyst/Realm.framework "$destination"
+        clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION-maccatalyst/RealmSwift.framework" "$destination" "RealmSwift.framework"
+        clean_retrieve "build/catalyst/Realm.framework" "$destination" "Realm.framework"
         ;;
 
     "xcframework")
@@ -1217,14 +1208,13 @@ EOM
             exit 1
           fi
 
-          if [ ! -d core ]; then
+          if [ ! -f core/version.txt ]; then
             sh build.sh download-sync
-            rm core
-            mv sync-* core
             mv core/librealm-ios.a core/librealmcore-ios.a
             mv core/librealm-macosx.a core/librealmcore-macosx.a
             mv core/librealm-tvos.a core/librealmcore-tvos.a
             mv core/librealm-watchos.a core/librealmcore-watchos.a
+            rm core/librealm*-dbg.a
           fi
 
           rm -rf include
@@ -1243,18 +1233,7 @@ EOM
           cp Realm/ObjectStore/src/util/apple/*.hpp include/util/apple
 
           echo '' > Realm/RLMPlatform.h
-          if [ -n "$COCOAPODS_VERSION" ]; then
-            # This variable is set for the prepare_command available
-            # from the 1.0 prereleases, which requires a different
-            # header layout within the header_mappings_dir.
-            cp Realm/*.h include
-          else
-            # For CocoaPods < 1.0, we need to scope the headers within
-            # the header_mappings_dir by another subdirectory to avoid
-            # Clang from complaining about non-modular headers.
-            mkdir -p include/Realm
-            cp Realm/*.h include/Realm
-          fi
+          cp Realm/*.h include
         else
           sh build.sh set-swift-version
         fi

+ 3 - 3
Carthage/Checkouts/realm-cocoa/dependencies.list

@@ -1,4 +1,4 @@
-VERSION=5.3.4
-REALM_CORE_VERSION=6.0.18
-REALM_SYNC_VERSION=5.0.15
+VERSION=5.3.5
+REALM_CORE_VERSION=6.0.19
+REALM_SYNC_VERSION=5.0.16
 REALM_OBJECT_SERVER_VERSION=3.28.5

+ 2 - 2
iOSClient/Database/NCManageDatabase.swift

@@ -1098,7 +1098,7 @@ class NCManageDatabase: NSObject {
         return tableDirectory.init(value: directory)
     }
     
-    @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String?, permissions: String?, serverUrl: String, richWorkspace: String?, account: String) {
+    @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String? = nil, permissions: String? = nil, serverUrl: String, richWorkspace: String? = nil, account: String) {
         
         let realm = try! Realm()
         realm.beginWrite()
@@ -1158,7 +1158,7 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    @objc func setDirectory(serverUrl: String, serverUrlTo: String?, etag: String?, ocId: String?, fileId: String?, encrypted: Bool, richWorkspace: String?, account: String) {
+    @objc func setDirectory(serverUrl: String, serverUrlTo: String? = nil, etag: String? = nil, ocId: String? = nil, fileId: String? = nil, encrypted: Bool, richWorkspace: String? = nil, account: String) {
         
         let realm = try! Realm()
 

+ 13 - 1
iOSClient/Networking/NCOperationQueue.swift

@@ -187,10 +187,18 @@ class NCOperationSynchronization: ConcurrentOperation {
                 let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
                 NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
                    if errorCode == 0 {
+                    
                         NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in
+                            
+                            // Directory
                             for metadata in metadatasFolder {
-                                NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
+                                let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "ocId == %@ ", metadata.ocId))
+                                if tableDirectory?.etag != metadata.etag {
+                                    NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
+                                }
                             }
+                            
+                            // Files
                             if metadatas.count > 0 {
                                 let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrlFileName, k_metadataStatusNormal))
                                 let metadatasChanged = NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult, withVerifyLocal: self.download)
@@ -202,7 +210,11 @@ class NCOperationSynchronization: ConcurrentOperation {
                                     }
                                 }
                             }
+                            
+                            // Update etag directory
+                            NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: metadataFolder.serverUrl, richWorkspace: metadataFolder.richWorkspace, account: metadataFolder.account)
                         }
+                    
                     } else if errorCode == 404 && self.metadata.directory {
                         NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: self.metadata.serverUrl, account: self.metadata.account)
                     }