Skip to content

Fix: Parse zip64 extra block by sentinel, not fixed order#19

Open
rayhankinan wants to merge 13 commits intoyeka:masterfrom
Match-Made:misc/zip64-support
Open

Fix: Parse zip64 extra block by sentinel, not fixed order#19
rayhankinan wants to merge 13 commits intoyeka:masterfrom
Match-Made:misc/zip64-support

Conversation

@rayhankinan
Copy link
Copy Markdown

Summary

Fixes a long-standing parsing bug inherited from upstream archive/zip. APPNOTE 4.5.3 specifies that the zip64 extra block in a central-directory entry contains only the fields whose 32-bit counterpart was sentinel-promoted (0xFFFFFFFF). The current parser reads the extra in fixed size, size, offset order based purely on remaining length, so it misparses any archive where the fields were promoted asymmetrically — for example an archive larger than 4 GiB whose individual entries are smaller than 4 GiB (only the offset gets promoted).

In that case the old parser consumed the offset bytes as UncompressedSize64 and left f.headerOffset stuck at 0xFFFFFFFF, making f.Open() fail.

Change

reader.go::readDirectoryHeader now checks each 32-bit counterpart for the sentinel value and consumes the matching 8-byte field only when promotion was indicated. A malformed archive that claims promotion without supplying enough bytes is now rejected with ErrFormat.

Test plan

  • TestZip64AsymmetricPromotion — hand-builds an archive (no testdata bytes; constructed in Go from struct fields and known offsets) with one stored entry whose central-directory offset is sentinel-promoted but whose sizes are not. Asserts both the parsed offset and a successful read of the entry's bytes.
  • TestZip64AsymmetricPromotion_TruncatedExtra — confirms ErrFormat when the extra claims promotion without data.
  • go test ./... — full suite green, including TestZip64, TestPasswordHelloWorldAes, TestZipCrypto, etc.

The hand-built fixture lives in reader_test.go rather than testdata/. It's a few hundred bytes assembled at test time from explicit struct fields, which is more reviewable than a binary blob and serves as a regression guard with no fixture-maintenance overhead.

rayhankinan and others added 13 commits May 4, 2026 14:18
* Fix: Change back to yeka/zip

* add test for multipart

* add test cases for multipart protected

* add test for zip64 format

* add test for multipart with multiple files

* change approach multifile multipart zip & fix diskNbr check for single file archive

* revert approach to previous

---------

Co-authored-by: rayhankinan <rayhankinan@gmail.com>
@rayhankinan rayhankinan changed the title [FIX] Parse zip64 extra block by sentinel, not fixed order Fix: Parse zip64 extra block by sentinel, not fixed order May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants