Add additional JSON object validation (#623)

* Add additional JSON object validation for queries made against OneDrive where a JSON response is expected and where that response is to be used and expected to be valid
This commit is contained in:
abraunegg 2019-08-24 16:26:08 +10:00 committed by GitHub
parent 488f756ecd
commit bc3853bc4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -420,9 +420,12 @@ final class SyncEngine
// download all new changes from a specified folder on OneDrive
void applyDifferencesSingleDirectory(string path)
{
log.vlog("Getting path details from OneDrive ...");
JSONValue onedrivePathDetails;
// test if the path we are going to sync from actually exists on OneDrive
try {
onedrive.getPathDetails(path);
onedrivePathDetails = onedrive.getPathDetails(path); // Returns a JSON String for the OneDrive Path
} catch (OneDriveException e) {
if (e.httpStatusCode == 404) {
// The directory was not found
@ -436,9 +439,8 @@ final class SyncEngine
}
}
// OK - the path on OneDrive should exist, get the driveId and rootId for this folder
log.vlog("Getting path details from OneDrive ...");
JSONValue onedrivePathDetails = onedrive.getPathDetails(path); // Returns a JSON String for the OneDrive Path
// Was the response a valid JSON Object?
if (onedrivePathDetails.type() == JSONType.object) {
string driveId;
string folderId;
@ -456,13 +458,16 @@ final class SyncEngine
// Apply any differences found on OneDrive for this path (download data)
applyDifferences(driveId, folderId);
} else {
// use the item id as folderId
folderId = onedrivePathDetails["id"].str; // Should give something like 12345ABCDE1234A1!101
// Apply any differences found on OneDrive for this path (download data)
applyDifferences(defaultDriveId, folderId);
}
} else {
// Log that an invalid JSON object was returned
log.error("ERROR: onedrive.getPathDetails call returned an invalid JSON Object");
}
}
// make sure the OneDrive root is in our database
@ -470,10 +475,12 @@ final class SyncEngine
{
log.vlog("Fetching details for OneDrive Root");
JSONValue rootPathDetails = onedrive.getDefaultRoot(); // Returns a JSON Value
// validate object is a JSON value
if (rootPathDetails.type() == JSONType.object) {
// valid JSON object
Item rootPathItem = makeItem(rootPathDetails);
// configure driveId and rootId for the OneDrive Root
// Set defaults for the root folder
string driveId = rootPathDetails["parentReference"]["driveId"].str; // Should give something like 12345abcde1234a1
string rootId = rootPathDetails["id"].str; // Should give something like 12345ABCDE1234A1!101
@ -486,6 +493,12 @@ final class SyncEngine
} else {
log.vlog("OneDrive Root exists in the database");
}
} else {
// Log that an invalid JSON object was returned
log.error("ERROR: onedrive.getDefaultRoot call returned an invalid JSON Object");
// Must exit here as we cant configure our required variables
exit(-1);
}
}
// create a directory on OneDrive without syncing
@ -587,6 +600,8 @@ final class SyncEngine
}
}
// validate that idDetails is a JSON value
if (idDetails.type() == JSONType.object) {
// Get the name of this 'Path ID'
if (("id" in idDetails) != null) {
// valid response from onedrive.getPathDetailsById(driveId, id) - a JSON item object present
@ -618,6 +633,10 @@ final class SyncEngine
log.vdebug("Sync Folder Child Path: ", syncFolderChildPath);
}
}
} else {
// Log that an invalid JSON object was returned
log.error("ERROR: onedrive.getPathDetailsById call returned an invalid JSON Object");
}
for (;;) {
// Due to differences in OneDrive API's between personal and business we need to get changes only from defaultRootId
@ -684,6 +703,8 @@ final class SyncEngine
}
}
// is changes a valid JSON response
if (changes.type() == JSONType.object) {
// Are there any changes to process?
if (("value" in changes) != null) {
auto nrChanges = count(changes["value"].array);
@ -794,6 +815,10 @@ final class SyncEngine
if (deltaLink) itemdb.setDeltaLink(driveId, id, deltaLink);
if ("@odata.nextLink" in changes) deltaLink = changes["@odata.nextLink"].str;
else break;
} else {
// Log that an invalid JSON object was returned
log.error("ERROR: onedrive.viewChangesById call returned an invalid JSON Object");
}
}
// delete items in idsToDelete
@ -1701,6 +1726,7 @@ final class SyncEngine
// upload done without error
writeln("done.");
// As the session.upload includes the last modified time, save the response
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
}
// OneDrive documentLibrary
@ -1747,6 +1773,7 @@ final class SyncEngine
// upload done without error
writeln("done.");
// As the session.upload includes the last modified time, save the response
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
} else {
// Due to https://github.com/OneDrive/onedrive-api-docs/issues/935 Microsoft modifies all PDF, MS Office & HTML files with added XML content. It is a 'feature' of SharePoint.
@ -1781,6 +1808,7 @@ final class SyncEngine
response = createFakeResponse(path);
// Log action to log file
log.fileOnly("Uploading modified file ", path, " ... done.");
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
return;
}
@ -2087,7 +2115,7 @@ final class SyncEngine
return;
}
}
// save the created directory
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
} else {
// Simulate a successful 'directory create' & save it to the dryRun database copy
@ -2126,6 +2154,7 @@ final class SyncEngine
// parent is in database
log.vlog("The parent for this path is in the local database - adding requested path (", path ,") to database");
auto res = onedrive.getPathDetails(path);
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(res);
}
} else {
@ -2380,6 +2409,7 @@ final class SyncEngine
// OneDrive Business Account - always use a session to upload
// The session includes a Request Body element containing lastModifiedDateTime
// which negates the need for a modify event against OneDrive
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
return;
}
@ -2396,6 +2426,7 @@ final class SyncEngine
response = createFakeResponse(path);
// Log action to log file
log.fileOnly("Uploading new file ", path, " ... done.");
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
return;
}
@ -2523,7 +2554,7 @@ final class SyncEngine
cTag = "";
}
}
// validate if path exists so mtime can be calculated
if (exists(path)) {
SysTime mtime = timeLastModified(path).toUTC();
uploadLastModifiedTime(parent.driveId, id, cTag, mtime);
@ -2531,6 +2562,10 @@ final class SyncEngine
// will be removed in different event!
log.log("File disappeared after upload: ", path);
}
} else {
// Log that an invalid JSON object was returned
log.error("ERROR: onedrive.simpleUpload or session.upload call returned an invalid JSON Object");
return;
}
} else {
// OneDrive Business account modified file upload handling
@ -2627,7 +2662,8 @@ final class SyncEngine
return;
}
}
writeln("done.");
writeln(" done.");
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
// Due to https://github.com/OneDrive/onedrive-api-docs/issues/935 Microsoft modifies all PDF, MS Office & HTML files with added XML content. It is a 'feature' of SharePoint.
// So - now the 'local' and 'remote' file is technically DIFFERENT ... thanks Microsoft .. NO way to disable this stupidity
@ -2650,6 +2686,7 @@ final class SyncEngine
response = createFakeResponse(path);
// Log action to log file
log.fileOnly("Uploading modified file ", path, " ... done.");
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
return;
}
@ -2763,6 +2800,7 @@ final class SyncEngine
}
}
// save the updated response from OneDrive in the database
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(response);
}
@ -2850,6 +2888,7 @@ final class SyncEngine
];
auto res = onedrive.updateById(fromItem.driveId, fromItem.id, diff, fromItem.eTag);
// update itemdb
// Is the response a valid JSON object - validation checking done in saveItem
saveItem(res);
}
}