Skip to content

fix(zip): complete ZIP64 malformed-header handling #3545

Description

@ibgreen

Problem

#3541 hardens ZIP64 extra-field traversal in central-directory headers, but related ZIP64 parsing paths still need follow-up:

  • parseZipLocalFileHeader() assumes the ZIP64 record starts at the beginning of the extra field and performs unchecked getBigUint64() reads. A missing or truncated ZIP64 record can still surface a raw RangeError through ZipFileSystem.fetch().
  • The central-directory disk-start field is read at byte offset 32, which is the file-comment-length field; disk start is at byte offset 34.
  • Disk start uses the 16-bit sentinel 0xffff and a 4-byte ZIP64 value, but the current expectation checks 0xffffffff, and the ZIP64 reader assumes an 8-byte field read.
  • Missing or truncated ZIP64 metadata currently has no explicit contract: some paths preserve sentinel values while others throw low-level DataView errors.

Follow-up to #3541.

Goals

  • Parse local-header and central-directory ZIP64 extra fields through a shared, bounds-checked record walker where practical.
  • Decode each ZIP64 value using its specified width and only when the corresponding legacy field contains its sentinel.
  • Correct central-directory disk-start parsing, or explicitly reject unsupported multi-disk archives with a controlled error.
  • Define consistent behavior for missing, truncated, and otherwise malformed ZIP64 metadata without leaking raw DataView exceptions.

Acceptance criteria

  • A local header with ZIP64 size sentinels and a missing or truncated ZIP64 record does not throw a raw RangeError.
  • Valid ZIP64 uncompressed size, compressed size, local-header offset, and disk-start values are decoded with the correct widths and ordering.
  • Extra fields preceding ZIP64 records and ZIP64-like byte sequences inside unrelated payloads are handled correctly.
  • Corrupt input produces the chosen documented fallback or a controlled archive-corruption error consistently across readdir(), stat(), and fetch().
  • Regression coverage is added in shared *.spec.ts tests so it runs in both Node and headless-browser projects.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions