Repository navigation
Copy only the remaining bytes in FileInfo.moveToNewLocation - #4916
Open
henriquejsza wants to merge 1 commit into
Open
henriquejsza wants to merge 1 commit into
henriquejsza wants to merge 1 commit into
Conversation
FileChannel.transferTo may transfer fewer bytes than requested. The copy loop passed the full size as the count on every call, so after a partial transfer a later call could read past the requested range and copy more than size bytes when the source index file is larger than size (the common case, since moveToNewLocation is called with getSizeSinceLastWrite()). Pass the remaining byte count (size - written) on each call instead. This also removes the now provably unreachable post-loop 'written <= 0 && size > 0' check reported in the issue. Add FileInfoTest covering a partial-transfer copy. Signed-off-by: henriquejsza <henriquejsza@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix #4736
Motivation
FileInfo.moveToNewLocationcopies the ledger index file to a new location withFileChannel.transferTo:transferTomay transfer fewer bytes than requested. Because the count passed toevery call is
size(not the number of bytes still to copy), a call after apartial transfer reads from position
writtenfor up tosizemore bytes. Whenthe source file holds more than
sizebytes, that copies past the requestedrange, so the new location can end up with more than
sizebytes. This mattersin practice:
moveToNewLocationis called withgetSizeSinceLastWrite(), whichcan be smaller than the actual file size.
The post-loop
written <= 0 && size > 0check reported in the issue isunreachable: when
size > 0the loop runs at least once and either throws orincrements
writtento a positive value.Changes
size - written) totransferToon eachiteration so exactly
sizebytes are copied.transferFullyhelper andremove the unreachable post-loop check.
FileInfoTestcovering a partial transfer, asserting that exactlysizebytes are copied.