Fix offset issue when reading StringFileInfo #79
Merged
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.
I ran into an issue while using this library to read version info from certain PE files. My main test case has been the exe of Powershell 7.3.4, but have found the same issue in other binaries. Using the latest revision of this library, reading the version info from pwsh.exe would lead to the following truncated and corrupted output:
Debugging the code, I discovered the issue appears to stem from the version parsing code's handling of alignment. The
ParseVersionResources
function keeps track of astringOffset
where it expects to find the next string, and passes it to theparseString
function. TheparseString
function calcuates its own offset into the file based on thestringOffset
passed to it, aligns the new offset, and then reads the string from the file using the aligned offset.parseString
then returns the length of the string toParseVersionResources
, where it is added to thestringOffset
to get the expected location of the next string.However, the length of the padding is not included in this calculation. As such, when
ParseVersionResources
adds the string length to its offset, it ends up being a few bytes short of where it should be, since it is adding the length of the string to a non aligned offset. As long as the difference between the expected location and the actual location is not a a multiple of four, the alignment process insideparseString
ends up fixing the problem. However in the case of the pwsh.exe binary I was examining, there were two cases where the difference between the expected offset and the actual offset was exactly four bytes. As a result, the alignment did not adjust the offset, and the code attempted to read the string four bytes short of where it should have, resulting in junk data being loaded.To fix this, I added a new private offset calculation function which returns the aligned offset, as well as the number of bytes added to achieve alignment. This latter value is added to the string length before being returned to
ParseVersionResources
, and gives the following correct result:I have written a test case around the Powershell binary, but it seems the gitignore rules prevent the inclusion of .exe files. It's not clear to me if I should try and force-add the executable. The binary is relatively small (about 200-odd kb), freely available and is open source software. However, I will defer to the maintainers of this project if they want the binary and the test case included.