Fix ZIP64 handling for Outlook OLM and other low-version producers#378
Open
xgimpx wants to merge 1 commit intoweichsel:developmentfrom
Open
Fix ZIP64 handling for Outlook OLM and other low-version producers#378xgimpx wants to merge 1 commit intoweichsel:developmentfrom
xgimpx wants to merge 1 commit intoweichsel:developmentfrom
Conversation
…ffset 0 Two issues prevented reading ZIP64 archives produced by Microsoft Outlook (OLM export) and potentially other producers: 1. ZIP64EndOfCentralDirectoryRecord.init rejected records where versionNeededToExtract < 4.5. Outlook writes ZIP64 structures with version 1.0 (since it only uses store compression). The ZIP64 EOCD signature is already validated, which is sufficient to identify the record. Removed the version guard. 2. effectiveCompressedSize, effectiveUncompressedSize, and effectiveRelativeOffsetOfLocalHeader used `> 0` to decide whether to use the ZIP64 value. This incorrectly rejected legitimate zero values — e.g. the first entry in an archive has offset 0, and empty files/directories have size 0. Changed to check whether the 32-bit field equals `.max` (the ZIP64 overflow indicator) instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two issues prevent ZIPFoundation from reading ZIP64 archives produced by Microsoft Outlook (OLM export) and potentially other ZIP producers that use ZIP64 structures with non-standard version fields:
Bug 1: ZIP64 EOCD version check too strict
ZIP64EndOfCentralDirectoryRecord.initrejects records whereversionNeededToExtract < 45(v4.5). Outlook writes ZIP64 structures withversionNeededToExtract = 10(v1.0) because it only usesstorecompression. The fallback to the standard EOCD — which has all fields set to0xFFFF/0xFFFFFFFF(ZIP64 overflow indicators) — makes the central directory offset point to 4 GB, past end of file, resulting in 0 entries.Fix: Removed the version guard. The ZIP64 EOCD Record signature (
0x06064B50) is already validated, which is sufficient to identify the record.Bug 2:
effectiveXXXproperties reject zero valueseffectiveCompressedSize,effectiveUncompressedSize, andeffectiveRelativeOffsetOfLocalHeaderuse> 0to decide whether to use the ZIP64 extended information value. This incorrectly treats0as "not present" instead of as a legitimate value:relativeOffsetOfLocalHeader = 0compressedSize = 0anduncompressedSize = 0When the ZIP64 value is rejected, the code falls back to the 32-bit field which contains
0xFFFFFFFF→ invalid offset → iteration fails on the first entry → 0 entries.Fix: Changed the condition from
value > 0toself.field == .max, which correctly checks whether the 32-bit field contains the ZIP64 overflow indicator and the ZIP64 value should be used.Diagnostic evidence
Tested with a real 41 MB Outlook OLM file (387 entries, 4 email accounts):
zipinfozipfileOLM file structure:
Changes
Archive+ZIP64.swift: RemovedversionNeededToExtract >= 45guardEntry.swift: Changedvalue > 0toself.field == .maxin all threeeffectiveXXXpropertiesZIPFoundationArchiveTests+ZIP64.swift: Updated test to expect acceptance of low-version ZIP64 recordsTest plan
🤖 Generated with Claude Code