From f3b4a3326d50fa704b619d3a166c3be313da6e40 Mon Sep 17 00:00:00 2001 From: abraunegg Date: Wed, 18 Sep 2024 11:25:55 +1000 Subject: [PATCH] Fix issue #2806: crash when run synchronize due to negative free space online (#2808) * When quota["remaining"].integer is converted, if negative, this leads to an issue due to 'ulong' type being used. Update how this value is converted, and the variable type to ensure that a negative number is stored as a negative number. * Fix logging output by removing duplicate output * Align logging messages to be consistent * Fix up output alignment for '0' and 'Not Available' --- src/sync.d | 68 +++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/sync.d b/src/sync.d index c3f68220..fd3f555c 100644 --- a/src/sync.d +++ b/src/sync.d @@ -69,7 +69,7 @@ struct DriveDetailsCache { string driveId; bool quotaRestricted; bool quotaAvailable; - ulong quotaRemaining; + long quotaRemaining; } struct DeltaLinkDetails { @@ -443,7 +443,10 @@ class SyncEngine { // - quotaAvailable; // - quotaRemaining; addOrUpdateOneDriveOnlineDetails(appConfig.defaultDriveId); - } + } + + // In some cases OneDrive Business configurations 'restrict' quota details thus is empty / blank / negative value / zero value + // When addOrUpdateOneDriveOnlineDetails() is called, messaging is provided if these are zero, negative or missing (thus quota is being restricted) // Fetch the details from cachedOnlineDriveData cachedOnlineDriveData = getDriveDetails(appConfig.defaultDriveId); @@ -451,35 +454,12 @@ class SyncEngine { // - cachedOnlineDriveData.quotaAvailable; // - cachedOnlineDriveData.quotaRemaining; - // In some cases OneDrive Business configurations 'restrict' quota details thus is empty / blank / negative value / zero - if (cachedOnlineDriveData.quotaRemaining <= 0) { - // free space is <= 0 .. why ? - if ("remaining" in defaultOneDriveDriveDetails["quota"]) { - if (appConfig.accountType == "personal") { - // zero space available - addLogEntry("ERROR: OneDrive account currently has zero space available. Please free up some space online."); - } else { - // zero space available is being reported, maybe being restricted? - addLogEntry("WARNING: OneDrive quota information is being restricted or providing a zero value. Please fix by speaking to your OneDrive / Office 365 Administrator."); - } - } else { - // json response was missing a 'remaining' value - if (appConfig.accountType == "personal") { - addLogEntry("ERROR: OneDrive quota information is missing. Potentially your OneDrive account currently has zero space available. Please free up some space online."); - } else { - // quota details not available - addLogEntry("ERROR: OneDrive quota information is being restricted. Please fix by speaking to your OneDrive / Office 365 Administrator."); - } - } - } - - // What did we set based on the data from the JSON + // What did we set based on the data from the JSON and cached drive data addLogEntry("appConfig.accountType = " ~ appConfig.accountType, ["debug"]); addLogEntry("appConfig.defaultDriveId = " ~ appConfig.defaultDriveId, ["debug"]); addLogEntry("cachedOnlineDriveData.quotaRemaining = " ~ to!string(cachedOnlineDriveData.quotaRemaining), ["debug"]); addLogEntry("cachedOnlineDriveData.quotaAvailable = " ~ to!string(cachedOnlineDriveData.quotaAvailable), ["debug"]); addLogEntry("cachedOnlineDriveData.quotaRestricted = " ~ to!string(cachedOnlineDriveData.quotaRestricted), ["debug"]); - } else { // Handle the invalid JSON response throw new AccountDetailsException(); @@ -2794,9 +2774,9 @@ class SyncEngine { } else { // zero or non-zero value or restricted if (!cachedOnlineDriveData.quotaRestricted){ - addLogEntry("Remaining Free Space: 0 KB", ["verbose"]); + addLogEntry("Remaining Free Space: 0 KB", ["verbose"]); } else { - addLogEntry("Remaining Free Space: Not Available", ["verbose"]); + addLogEntry("Remaining Free Space: Not Available", ["verbose"]); } } } @@ -4453,7 +4433,7 @@ class SyncEngine { JSONValue currentDriveQuota; bool quotaRestricted = false; // Assume quota is not restricted unless "remaining" is missing bool quotaAvailable = false; - ulong quotaRemainingOnline = 0; + long quotaRemainingOnline = 0; string[3][] result; OneDriveApi getCurrentDriveQuotaApiInstance; @@ -4500,11 +4480,20 @@ class SyncEngine { // If 'business' accounts, if driveId == defaultDriveId, then we will have data // If 'business' accounts, if driveId != defaultDriveId, then we will have data, but it will be a 0 value addLogEntry("Quota Details: " ~ to!string(currentDriveQuota), ["debug"]); + JSONValue quota = currentDriveQuota["quota"]; - auto quota = currentDriveQuota["quota"]; if ("remaining" in quota) { - quotaRemainingOnline = quota["remaining"].integer; + // Issue #2806 + // If this is a negative value, quota["remaining"].integer can potentially convert to a huge positive number. Convert a different way. + string tempQuotaRemainingOnlineString = to!string(quota["remaining"]); + long tempQuotaRemainingOnlineValue = to!long(tempQuotaRemainingOnlineString); + + // Update quotaRemainingOnline to use the converted value + quotaRemainingOnline = tempQuotaRemainingOnlineValue; + + // Set the applicable 'quotaAvailable' value quotaAvailable = quotaRemainingOnline > 0; + // If "remaining" is present but its value is <= 0, it's not restricted but exhausted if (quotaRemainingOnline <= 0) { if (appConfig.accountType == "personal") { @@ -4516,7 +4505,14 @@ class SyncEngine { } else { // "remaining" not present, indicating restricted quota information quotaRestricted = true; - addLogEntry("Quota information is restricted or not available for this drive.", ["verbose"]); + + // what sort of account type is this? + if (appConfig.accountType == "personal") { + addLogEntry("ERROR: OneDrive quota information is missing. Your OneDrive account potentially has zero space available. Please free up some space online."); + } else { + // quota details not available + addLogEntry("WARNING: OneDrive quota information is being restricted. Please fix by speaking to your OneDrive / Office 365 Administrator."); + } } } else { // When valid quota details are not fetched @@ -8510,7 +8506,7 @@ class SyncEngine { bool quotaRestricted; bool quotaAvailable; - ulong quotaRemaining; + long quotaRemaining; // Get the data from online auto onlineDriveData = getRemainingFreeSpaceOnline(driveId); @@ -8616,7 +8612,7 @@ class SyncEngine { void updateDriveDetailsCache(string driveId, bool quotaRestricted, bool quotaAvailable, ulong localFileSize) { // As each thread is running differently, what is the current 'quotaRemaining' for 'driveId' ? - ulong quotaRemaining; + long quotaRemaining; DriveDetailsCache cachedOnlineDriveData; cachedOnlineDriveData = getDriveDetails(driveId); quotaRemaining = cachedOnlineDriveData.quotaRemaining; @@ -8628,7 +8624,7 @@ class SyncEngine { if (quotaRemaining <= 0) { if (appConfig.accountType == "personal"){ // zero space available - addLogEntry("ERROR: OneDrive account currently has zero space available. Please free up some space online or purchase additional space."); + addLogEntry("ERROR: OneDrive account currently has zero space available. Please free up some space online or purchase additional capacity."); quotaRemaining = 0; quotaAvailable = false; } else { @@ -8647,7 +8643,7 @@ class SyncEngine { void freshenCachedDriveQuotaDetails() { foreach (driveId; onlineDriveDetails.keys) { // Update this driveid quota details - addLogEntry("Freshen Quota Details: " ~ driveId, ["debug"]); + addLogEntry("Freshen Quota Details for this driveId: " ~ driveId, ["debug"]); addOrUpdateOneDriveOnlineDetails(driveId); } }