diff options
author | Simon Tatham <anakin@pobox.com> | 2017-05-16 20:11:53 +0100 |
---|---|---|
committer | Simon Tatham <anakin@pobox.com> | 2017-05-16 20:11:53 +0100 |
commit | 4aa85aa621dd2fd0b33a74ceb6821213846df7da (patch) | |
tree | c14095d41b4eb977c4edab4fc5ba25ed5d2ed93d | |
parent | dc057115b5068fe6edf209a706a43893a67f3469 (diff) | |
download | wix-on-linux-4aa85aa621dd2fd0b33a74ceb6821213846df7da.tar.gz wix-on-linux-4aa85aa621dd2fd0b33a74ceb6821213846df7da.tar.bz2 wix-on-linux-4aa85aa621dd2fd0b33a74ceb6821213846df7da.zip |
Fix checksum calculation in CAB data records.
[MS-CAB] is pretty unclearly worded in this area. Turns out that if
the sequence of bytes being checksummed is not a multiple of 4 bytes,
you are supposed to _first_ reverse the order of the trailing (n % 4)
bytes, and _then_ append zero bytes to pad to a multiple of 4, before
you do the main checksum operation of XORing together all the 32-bit
words of the input.
-rwxr-xr-x | makecab.py | 6 |
1 files changed, 5 insertions, 1 deletions
@@ -34,7 +34,11 @@ def packtime(h,m,s): | |||
34 | return ((h << 11) | (m << 5) | (s >> 1)) | 34 | return ((h << 11) | (m << 5) | (s >> 1)) |
35 | 35 | ||
36 | def checksum(data): | 36 | def checksum(data): |
37 | data += "\0" * (3 & -len(data)) # pad to multiple of 4 bytes | 37 | data_full_words = data[:len(data) & ~3] |
38 | data_last_word = data[len(data_full_words):] | ||
39 | data_last_word = "".join(reversed(data_last_word)) | ||
40 | data_last_word += "\0" * (3 & -len(data)) # pad to multiple of 4 bytes | ||
41 | data = data_full_words + data_last_word | ||
38 | toret = 0 | 42 | toret = 0 |
39 | for offset in xrange(0, len(data), 4): | 43 | for offset in xrange(0, len(data), 4): |
40 | toret ^= struct.unpack_from("<L", data, offset)[0] | 44 | toret ^= struct.unpack_from("<L", data, offset)[0] |