robbederks/downzip

View on GitHub
src/zip/Zip64Format.md

Summary

Maintainability
Test Coverage
# Archive format:
    [FILE #1
    ...
    FILE #N]
    ARCHIVE DECRYPTION HEADER
    ARCHIVE EXTRA DATA RECORD
    [CENTRAL DIRECTORY HEADER 1
    ...
    CENTRAL DIRECTORY HEADER N]
    ZIP64 END OF CENTRAL DIRECTORY RECORD
    ZIP64 END OF CENTRAL DIRECTORY LOCATOR
    END OF CENTRAL DIRECTORY RECORD

# File format:
    LOCAL FILE HEADER
    ENCRYPTION HEADER (NOT IMPLEMENTED)
    DATA
    DATA DESCRIPTOR

# Local file header format:
Header size: `30 bytes + file name length + extra field length`
```
    SIGNATURE (0x04034B50)
    VERSION (PKZip 4.5 added support for ZIP64: 45 = 0x002D)
    GENERAL PURPOSE FLAGS (0x0808):
        0: ENCRYPTED (NO ENCRYPTION: 0)
        1-2: COMPRESSION OPTION (N/A: 00)
        3: DATA DESCRIPTOR (YES: 1)
        4: ENHANCED DEFLATION (N/A: 0)
        5: COMPRESSED PATCHED DATA (N/A: 0)
        6: STRONG ENCRYPTION (N/A: 0)
        7-10: UNUSED (0000)
        11: LANGUAGE ENCODING (UTF-8: 1)
        12: RESERVED (0)
        13: MASK HEADER VALUES (NO: 0)
        14: RESERVED (0)
        15: RESERVED (0)
    COMPRESSION METHOD (NO COMPRESSION: 0x0000)
    MODIFICATION TIME (NOW):
        0-4: seconds divided by 2
        5-10: minutes
        11-15: hours
    MODIFICATION DATE (TODAY):
        0-4: day
        5-8: month
        9-15: (year - 1980)
    CRC32 (SINCE USING DATA DESCRIPTORS: 0x00000000)
    COMPRESSED SIZE (IF USING ZIP64: 0xFFFFFFFF)
    UNCOMPRESSED SIZE (IF USING ZIP64: 0xFFFFFFFF)
    FILE NAME LENGTH (IN BYTES, 0x0000)
    EXTRA FIELD LENGTH (IN BYTES, 0x0000)
    FILE NAME + PATH (NOT USING PATH, SO JUST THE NAME)
    EXTRA FIELDS
```

# ZIP64 Extra field format:
Extra field size: `32 bytes`
```
    HEADER ID (ZIP64: 0x0001)
    DATA SIZE (NUMBER OF BYTES IN THIS EXTRA FIELD, 2 bytes)
    ORIGINAL FILE SIZE (0x0000000000000000 (8 bytes))
    COMPRESSED FILE SIZE (0x0000000000000000 (8 bytes))
    RELATIVE HEADER OFFSET (0x0000000000000000 (8 bytes))
    DISK START NUMBER (0x00000000 (4 bytes))
```

# Data descriptor format:
Data descriptor size: `12 or 20 bytes depending on zip64`
```
    CRC32 (4 bytes)
    COMPRESSED SIZE (IF USING ZIP64: 8 bytes, OTHERWISE 4 bytes)
    UNCOMPRESSED SIZE (IF USING ZIP64: 8 bytes, OTHERWISE 4 bytes)
```

# Central directory header format:
Central directory header size: `46 bytes + file name length + extra field length`
```
    SIGNATURE (0x02014B50)
    VERSION MADE BY (2 bytes: PKZip 4.5 added support for ZIP64: 45 = 0x002D)
    VERSION NEEDED TO EXTRACT (2 bytes: PKZip 4.5 added support for ZIP64: 45 = 0x002D)
    GENERAL PURPOSE FLAGS (0x0808):
        0: ENCRYPTED (NO ENCRYPTION: 0)
        1-2: COMPRESSION OPTION (N/A: 00)
        3: DATA DESCRIPTOR (YES: 1)
        4: ENHANCED DEFLATION (N/A: 0)
        5: COMPRESSED PATCHED DATA (N/A: 0)
        6: STRONG ENCRYPTION (N/A: 0)
        7-10: UNUSED (0000)
        11: LANGUAGE ENCODING (UTF-8: 1)
        12: RESERVED (0)
        13: MASK HEADER VALUES (NO: 0)
        14: RESERVED (0)
        15: RESERVED (0)
    COMPRESSION METHOD (NO COMPRESSION: 0x0000)
    MODIFICATION TIME (NOW):
        0-4: seconds divided by 2
        5-10: minutes
        11-15: hours
    MODIFICATION DATE (TODAY):
        0-4: day
        5-8: month
        9-15: (year - 1980)
    CRC32 (4 BYTES)
    COMPRESSED SIZE (IF USING ZIP64: 0xFFFFFFFF)
    UNCOMPRESSED SIZE (IF USING ZIP64: 0xFFFFFFFF)
    FILE NAME LENGTH (IN BYTES, 0x0000)
    EXTRA FIELD LENGTH (IN BYTES, 0x0000)
    FILE COMMENT LENGTH (IN BYTES, 0x0000)
    DISK # START (0x0000)
    INTERNAL ATTRIBUTES (0x0000):
        0: Apparent ASCII/Text file
        1: Reserved
        2: Control field records precede logical records
        3-15: Unused
    EXTERNAL ATTRIBUTES (NOT IMPORTANT: 0x00000000)
    LOCAL HEADER OFFSET (BYTES FROM FIRST DISK START: 0x00000000)
    FILE NAME
    EXTRA FIELD (see above)
    FILE COMMENT
```

# ZIP64 End of central directory record
ZIP64 End of central directory record size: `56 bytes`
```
    SIGNATURE (0x06064b50)
    SIZE OF THIS RECORD, MINUS THESE 12 BYTES (8 BYTES)
    VERSION MADE BY (2 bytes: PKZip 4.5 added support for ZIP64: 45 = 0x002D)
    VERSION NEEDED TO EXTRACT (2 bytes: PKZip 4.5 added support for ZIP64: 45 = 0x002D)
    NUMBER OF THIS DISK (4 BYTES)
    NUMBER OF DISK WITH START OF CENTRAL DIRECTORY (4 BYTES)
    TOTAL NUMBER OF ENTRIES IN CENTRAL DIRECTORY ON THIS DISK (8 BYTES)
    TOTAL NUMBER OF ENTRIES IN CENTRAL DIRECTORY (8 BYTES)
    SIZE OF CENTRAL DIRECTORY (8 BYTES)
    OFFSET OF START OF CENTRAL DIRECTORY FROM STARTING DISK NUMBER (8 BYTES)
    ZIP64 EXTENSIBLE DATA SECTOR (VARIABLE SIZE, not used in our case?)
```

# ZIP64 End of central directory locator
ZIP64 End of central directory locator size: `20 bytes`
```
    SIGNATURE (0x07064b50)
    NUMBER OF DISK WITH START OF ZIP64 END OF CENTRAL DIRECTORY HEADER (4 BYTES)
    RELATIVE OFFSET OF ZIP64 END OF CENTRAL DIRECTORY RECORD (8 BYTES)
    TOTAL NUMBER OF DISKS (4 BYTES)
```

# End of central directory record
ZIP64 End of central directory record size: `22 bytes`
```
    SIGNATURE (0x06054b50)
    NUMBER OF THIS DISK (2 BYTES)
    NUMBER OF DISK WITH START OF CENTRAL DIRECTORY (2 BYTES)
    TOTAL NUMBER OF ENTRIES IN CENTRAL DIRECTORY ON THIS DISK (2 BYTES)
    TOTAL NUMBER OF ENTRIES IN CENTRAL DIRECTORY (2 BYTES)
    SIZE OF THE CENTRAL DIRECTORY (4 BYTES)
    OFFSET OF START OF CENTRAL DIRECTORY FROM STARTING DISK NUMBER (4 BYTES)
    FILE COMMENT LENGTH (2 BYTES)
    FILE COMMENT (VARIABLE LENGTH)
```