From 66764f279d89ca320b8737369fdd56e7f11731fe Mon Sep 17 00:00:00 2001 From: abraunegg Date: Sat, 13 Jul 2019 15:42:35 +1000 Subject: [PATCH] Add explicit check for hashes being returned from OneDrive (Issue #591) (#592) * Add explicit check for hashes to be returned in cases where OneDrive API fails to provide them despite requested to do so * Add comparison with sha1 if OneDrive provides that rather than quickXor --- src/sync.d | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/sync.d b/src/sync.d index 9e2878b4..aafc372b 100644 --- a/src/sync.d +++ b/src/sync.d @@ -79,11 +79,21 @@ private bool hasId(const ref JSONValue item) return ("id" in item) != null; } +private bool hasHashes(const ref JSONValue item) +{ + return ("hashes" in item["file"]) != null; +} + private bool hasQuickXorHash(const ref JSONValue item) { return ("quickXorHash" in item["file"]["hashes"]) != null; } +private bool hasSha1Hash(const ref JSONValue item) +{ + return ("sha1Hash" in item["file"]["hashes"]) != null; +} + private bool isDotFile(string path) { // always allow the root @@ -1150,13 +1160,26 @@ final class SyncEngine // filesize missing log.vdebug("WARNING: fileDetails['size'] is missing"); } - - if (hasQuickXorHash(fileDetails)) { - // Use the configured quickXorHash as reported by OneDrive - OneDriveFileHash = fileDetails["file"]["hashes"]["quickXorHash"].str; + + if (hasHashes(fileDetails)) { + // File details returned hash details + // QuickXorHash + if (hasQuickXorHash(fileDetails)) { + // Use the configured quickXorHash as reported by OneDrive + if (fileDetails["file"]["hashes"]["quickXorHash"].str != "") { + OneDriveFileHash = fileDetails["file"]["hashes"]["quickXorHash"].str; + } + } + // Check for Sha1Hash + if (hasSha1Hash(fileDetails)) { + // Use the configured sha1Hash as reported by OneDrive + if (fileDetails["file"]["hashes"]["sha1Hash"].str != "") { + OneDriveFileHash = fileDetails["file"]["hashes"]["sha1Hash"].str; + } + } } else { - // filesize missing - log.vdebug("WARNING: fileDetails['file']['hashes']['quickXorHash'] is missing"); + // file hash data missing + log.vdebug("WARNING: fileDetails['file']['hashes'] is missing - unable to compare file hash after download"); } try { @@ -1194,8 +1217,11 @@ final class SyncEngine // A 'file' was downloaded - does what we downloaded = reported fileSize or if there is some sort of funky local disk compression going on // does the file hash OneDrive reports match what we have locally? string quickXorHash = computeQuickXorHash(path); - if ((getSize(path) == fileSize) || (OneDriveFileHash == quickXorHash)) { + string sha1Hash = computeSha1Hash(path); + + if ((getSize(path) == fileSize) || (OneDriveFileHash == quickXorHash) || (OneDriveFileHash == sha1Hash)) { // downloaded matches either size or hash + log.vdebug("Downloaded file matches reported size and or reported file hash"); setTimes(path, item.mtime, item.mtime); } else { // size error? @@ -1204,7 +1230,7 @@ final class SyncEngine log.error("ERROR: File download size mis-match. Increase logging verbosity to determine why."); } // hash error? - if (OneDriveFileHash != quickXorHash) { + if ((OneDriveFileHash != quickXorHash) || (OneDriveFileHash != sha1Hash)) { // downloaded file hash does not match log.error("ERROR: File download hash mis-match. Increase logging verbosity to determine why."); }