From c73c0aa608c5b7089ae747430f9e4f2e1b08e3b1 Mon Sep 17 00:00:00 2001 From: abraunegg Date: Thu, 10 Nov 2022 06:50:37 +1100 Subject: [PATCH] Fix application crash when local file is changed to a symbolic link with non-existent target (#2211) * Add a try & catch block for testing if the file exists locally to catch any filesystem error that may be generated * Test path to be valid if a symbolic link --- src/sync.d | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/sync.d b/src/sync.d index f4e87d81..33bfecc4 100644 --- a/src/sync.d +++ b/src/sync.d @@ -2564,7 +2564,7 @@ final class SyncEngine log.vdebug("OneDrive change is an update to an existing local item"); applyChangedItem(oldItem, oldPath, item, path); } else { - log.vdebug("OneDrive change is a new local item"); + log.vdebug("OneDrive change is potentially a new local item"); // Check if file should be skipped based on size limit if (isItemFile(driveItem)) { if (cfg.getValueLong("skip_size") != 0) { @@ -2621,7 +2621,33 @@ final class SyncEngine // download an item that was not synced before private void applyNewItem(const ref Item item, const(string) path) { - if (exists(path)) { + bool localPathExists; + // Test for the local path existence + try { + // Does the path actually exist locally? + if (exists(path)) { + // flag that the path exists locally + localPathExists = true; + } + } catch (FileException e) { + // file system generated an error message + // display the error message + displayFileSystemErrorMessage(e.msg, getFunctionName!({})); + return; + } + + if (localPathExists) { + // test if a bad symbolic link + if (isSymlink(path)) { + log.vdebug("Path on local disk is a symbolic link ........"); + if (!exists(readLink(path))) { + // reading the symbolic link failed + log.vdebug("Reading the symbolic link target failed ........ "); + log.logAndNotify("Skipping item - invalid local symbolic link: ", path); + return; + } + } + // path exists locally // Query DB for new remote item in specified path string itemSource = "remote";