Repository navigation
Fix Zip64 data descriptors on non-seekable streams - #136963
Conversation
|
Azure Pipelines: Successfully started running 3 pipeline(s). 12 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @karelz, @dotnet/area-system-io-compression |
|
@dotnet-policy-service agree |
There was a problem hiding this comment.
🔵 Needs a closer look
Requiring ZIP64 for all non-empty entries on non-seekable streams, even small entries, needs maintainer confirmation of downstream-reader compatibility trade-offs and breaking-change handling.
No open issues 🎉
What changed in this PR
Fixes ZIP header and data-descriptor consistency in System.IO.Compression for non-seekable output, allowing readers to determine descriptor width before reading entry data.
Changes:
- Declares Zip64 before writing streamed entry data and uses 64-bit descriptor sizes, including for small entries.
- Preserves local Zip64 declarations during metadata-only updates that retain existing descriptors.
- Extends synchronous and asynchronous regression tests for creation and metadata updates.
Streamed entries containing data now require a Zip64-capable reader; small entries gain 28 bytes of metadata. No public API changes are introduced.
| File | Description |
|---|---|
src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.cs |
Verifies retained Zip64 headers and descriptors after metadata updates. |
src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.cs |
Checks streamed Zip64 structure and exercises asynchronous entry writes. |
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs |
Reports whether parsed local extra fields contain a Zip64 declaration. |
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.Async.cs |
Returns the same Zip64 declaration information during asynchronous parsing. |
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs |
Declares streamed Zip64 entries, selects descriptor width, and preserves retained declarations. |
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs |
Records local Zip64 declarations during asynchronous loading. |
Review effort: Balanced
|
Added When you commit this breaking change:
Tagging @dotnet/compat for awareness of the breaking change. |
Writing an entry larger than 4 GiB to a non-seekable stream currently emits a ZIP32 local header followed by a Zip64 data descriptor, so readers using local headers cannot determine the descriptor width
Declare Zip64 before writing streamed entry data and always use 64-bit descriptor sizes for those entries, including small entries
Preserve the original local Zip64 declaration when Update mode rewrites metadata while retaining the existing descriptor
Extend the existing creation and metadata-update tests for both synchronous and asynchronous paths
Compatibility: streamed entries with data now require a Zip64-capable reader and small streamed entries gain 28 bytes of metadata
Applications requiring ZIP32 compatibility for small entries can write to a seekable stream
No public API changes
Local validation on macOS arm64:
unzip -tand reading the following entry through pipedtarinputSystem.IO.Compression: 3026 regular tests and 92 OuterLoop tests passedSystem.IO.Compression.ZipFile: 379 regular tests and 16 OuterLoop tests passedSystem.IO.Compression: 1283 tests passed, including all four regression casesgit diff --checkzip_CreateTests.cs:82as the unchanged baselineBrowser builds used
/p:EnableHotReloadInRuntimeConfigDevFile=falsefor the SDK issue tracked in dotnet/sdk#56656, with no SDK or build-system changes in this PRThe browser host logs
Aborted(Assertion failed)during teardown afterWASM EXIT 0in both the unmodified-product control and passing patched run, while XHarness and the build return 0Resolves #127389
Note
This PR was prepared with AI assistance