mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-03 21:23:38 +00:00
Streams larger than uint.MaxValue cause broken zip files
#154
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @kenkendk on GitHub (Mar 9, 2017).
I have tracked down an issue causing failures when attempting to read zip files with SharpCompress (files created AND read by SharpCompress).
The error message is
Unknown header {value}, where{value}is some random bytes from the file. This is similar to issue #33, but they report it for a much smaller file (I have tested the file mentioned in the issue, and it does not appear to cause any errors).The problem is that the Central Directory Entry is limited to storing the
SizeandHeaderOffsetasuintvalues.There are no checks in SharpCompress if this limit is exceeded, causing the creation to succeed, but then failing to read them later. In the example below, this is done with a single file of 4GB size, but it can also be achieved with many smaller files, as long as the
HeaderOffsetvalue becomes larger than2^32.There is another issue in that the number of files are limited to
ushort, but this appears to have no effects other than reporting the wrong number of files, which is not directly exposed.A workaround to reading such a file is using the forward-only interface, which does not read the Central Directory Entry, and this can correctly read the file contents unless there is a single file larger than
2^32.I can think of two solutions:
Prevent creating files with offsets larger than
2^32, simply throwing an exception if this is detected.Support zip64, which replaces the size and offset with
0xffffffffand stores a 64bit value in the extended information.I think support for zip64 is the better choice here. Reading support for zip64 has already been added, but it requires that the correct zip64 records are written.
I will see if I can make a PR that adds zip64 support.
Example code that reproduces the issue: