Majored / rs-async-zip

An asynchronous ZIP archive reading/writing crate.
MIT License
123 stars 40 forks source link

Incorrect parsing of zip64 extended information field #108

Closed VivekPanyam closed 10 months ago

VivekPanyam commented 10 months ago

The code that parses the zip64 extended information field checks that the field is long enough to contain both the compressed and uncompressed size of the entry.

https://github.com/Majored/rs-async-zip/blob/802c96192d958fd699018cefc0e58058ef8b7694/src/spec/extra_field.rs#L102-L126

For parsing local file headers, this is correct because both the compressed and uncompressed size are required to be present.

However, according to the ZIP spec, the zip64 extended field in the central directory is not always required to contain compressed and uncompressed size (see below).

This leads to failures when parsing valid zip64 files.

Relevant section of the spec:

   4.5.3 -Zip64 Extended Information Extra Field (0x0001):

      The following is the layout of the zip64 extended 
      information "extra" block. If one of the size or
      offset fields in the Local or Central directory
      record is too small to hold the required data,
      a Zip64 extended information record is created.
      The order of the fields in the zip64 extended 
      information record is fixed, but the fields MUST
      only appear if the corresponding Local or Central
      directory record field is set to 0xFFFF or 0xFFFFFFFF.

      Note: all fields stored in Intel low-byte/high-byte order.

        Value      Size       Description
        -----      ----       -----------
(ZIP64) 0x0001     2 bytes    Tag for this "extra" block type
        Size       2 bytes    Size of this "extra" block
        Original 
        Size       8 bytes    Original uncompressed file size
        Compressed
        Size       8 bytes    Size of compressed data
        Relative Header
        Offset     8 bytes    Offset of local header record
        Disk Start
        Number     4 bytes    Number of the disk on which
                              this file starts 

      This entry in the Local header MUST include BOTH original
      and compressed file size fields. If encrypting the 
      central directory and bit 13 of the general purpose bit
      flag is set indicating masking, the value stored in the
      Local Header for the original file size will be zero.

Note that it says "This entry in the Local header MUST include BOTH original and compressed file size fields" otherwise they "MUST only appear if the corresponding Local or Central directory record field is set to 0xFFFF or 0xFFFFFFFF." (emphasis mine)

St4NNi commented 10 months ago

This is more or less the read version of the write related issues #105 & https://github.com/Majored/rs-async-zip/pull/106 so I guess there needs to be more fixed regarding Zip64 and the CD / local header parsing / creation.