mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-09 21:24:08 +00:00
[PR #1169] Fix ZIP parsing failure on non-seekable streams with short reads #1611
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Original Pull Request: https://github.com/adamhathcock/sharpcompress/pull/1169
State: closed
Merged: Yes
Fix ZIP parsing regression with short reads on non-seekable streams
Completed:
BinaryReaderdoesn't handle short reads properly on non-seekable streamsFix Details:
The regression occurred because
SharpCompressStream.Read()with buffering enabled would return short reads when the underlying stream returned less data than requested. This causedBinaryReaderto receive incomplete data when parsing ZIP headers, leading toZlibExceptionfailures depending on the chunking pattern.Solution: Modified
SharpCompressStreamto implement buffer fill methods that follow theReadFully/ReadFullyAsyncpattern fromUtility.cs. These methods read from the underlying stream in a loop until the internal buffer is filled or EOF is reached, but return the actual count read (rather than a boolean) to handle EOF gracefully.Changes made to
SharpCompressStream.cs:FillBuffer()to follow the ReadFully pattern (same logic asUtility.ReadFullybut returns count)FillBufferAsync()to follow the ReadFullyAsync patternFillBufferMemoryAsync()to follow the ReadFullyAsync patternTest coverage:
ZipShortReadTestswith 9 test cases covering various chunking patternsSummary
This fix resolves the reported issue where SharpCompress ZIP parsing became sensitive to Stream.Read chunking patterns on non-seekable streams. The solution follows the established ReadFully pattern used elsewhere in the codebase.
Original prompt
This section details on the original issue you should resolve
<issue_title>Regression: ZIP parsing fails depending on Stream.Read chunking on non-seekable streams</issue_title>
<issue_description>Hi,
I’m hitting what looks like a stream chunking sensitivity regression when reading ZIP archives from a non-seekable stream. With the exact same ZIP bytes, SharpCompress will sometimes fail depending only on how the underlying
Stream.Read()splits the data.Regression note
The exact same code path works correctly with SharpCompress 0.40.0.
The failure (
ZlibExceptionin the chunked case) starts occurring in newer versions.Context / real-world scenario
This happens in a real ASP.NET Core streaming pipeline (multipart/form-data):
HttpRequest.BodyMultipartReader(multipart/form-data)ReaderFactory.Open(...).MoveToNextEntry()A seemingly unrelated change (for example changing a text field value from
"my-value"to"my-valu") shifts the alignment of the ZIP part by 1 byte, which changes the short-read pattern seen by SharpCompress and triggers a failure.To make this report independent of ASP.NET / multipart, the repro below uses a custom non-seekable stream that returns legal short reads.
Reproduction
This snippet (with stream.zip) reads the same ZIP bytes three ways:
MemoryStreamOnly case (3) fails with a
ZlibException. Wrapping the stream with a simple coalescing wrapper fixes the issue.