rubyzip/rubyzip — pull request #99 by jstanley0 (2013-09-28 03:06:40+00:00)
Title: Add read/write support for zip64 extensions

This commit adds the capability of creating archives larger than 4GB via zip64 extensions. It also fixes bugs reading archives of this size (specifically, the 64-bit offset of the local file header was not being read from the central directory entry, so files starting beyond 4GB in the zip file could not be read).

To maximize compatibility with other readers, zip64 extensions are used only when required. Unfortunately, at the time we write a local file header, we don't know the size of the file and thus whether a Zip64 Extended Information Extra Field will be required. Therefore this commit writes a 'placeholder' extra field to reserve space for the zip64 entry, which will be written if necessary when we update the local entry with the final sizes and CRC. I use the signature "\x99\x99" for this field, following the example of DotNetZip which does the same.

This commit also adds a rake task, zip64_full_test, which fully tests zip64 by actually creating and verifying a 4GB zip file. Please note, however, that this test requires UnZip version 6.00 or newer, which may not be supplied by your OS. This test doesn't run along with the main unit tests because it takes a few minutes to complete.

Note also that previous code packed 64-bit values using the "Q" format string, which uses host byte order. I changed these to "Q<", which is little-endian (as the zip format uses). This format specifier was introduced in Ruby 1.9, however; 1.8.7 ignores the '<' and just reads host byte order, meaning zip64 will still be broken on big-endian machines on ruby 1.8.7.