Fix application crash due to a conversion overflow when calculating file offset for session uploads (#1558)

* Fix an unhandled application crash when calculating the required offset for a file fragment size when resuming a session upload
This commit is contained in:
abraunegg 2021-07-12 05:59:32 +10:00 committed by GitHub
parent 34f7a379f6
commit 1fbe1d34a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 2 deletions

View File

@ -769,6 +769,7 @@ final class OneDriveApi
auto file = File(filepath, "rb");
file.seek(offset);
string contentRange = "bytes " ~ to!string(offset) ~ "-" ~ to!string(offset + offsetSize - 1) ~ "/" ~ to!string(fileSize);
log.vdebugNewLine("contentRange: ", contentRange);
// function scopes
scope(exit) {
@ -789,7 +790,8 @@ final class OneDriveApi
http.url = uploadUrl;
http.addRequestHeader("Content-Range", contentRange);
http.onSend = data => file.rawRead(data).length;
http.contentLength = offsetSize;
// convert offsetSize to ulong
http.contentLength = to!ulong(offsetSize);
auto response = perform();
// TODO: retry on 5xx errors
checkHttpCode(response);

View File

@ -173,6 +173,7 @@ struct UploadSession
Progress p = new Progress(iteration);
p.title = "Uploading";
long fragmentCount = 0;
long fragSize = 0;
// Initialise the download bar at 0%
p.next();
@ -181,7 +182,23 @@ struct UploadSession
fragmentCount++;
log.vdebugNewLine("Fragment: ", fragmentCount, " of ", iteration);
p.next();
long fragSize = fragmentSize < fileSize - offset ? fragmentSize : fileSize - offset;
log.vdebugNewLine("fragmentSize: ", fragmentSize, "offset: ", offset, " fileSize: ", fileSize );
fragSize = fragmentSize < fileSize - offset ? fragmentSize : fileSize - offset;
log.vdebugNewLine("Using fragSize: ", fragSize);
// fragSize must not be a negative value
if (fragSize < 0) {
// Session upload will fail
// not a JSON object - fragment upload failed
log.vlog("File upload session failed - invalid calculation of fragment size");
if (exists(sessionFilePath)) {
remove(sessionFilePath);
}
// set response to null as error
response = null;
return response;
}
// If the resume upload fails, we need to check for a return code here
try {
response = onedrive.uploadFragment(