mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-03 21:23:38 +00:00
EntryStream.Dispose() calls Flush() on Deflate/LZMA streams causing NotSupportedException on non-seekable streams #765
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?
Originally created by @rleroux-regnology on GitHub (Jan 22, 2026).
Originally assigned to: @adamhathcock, @Copilot on GitHub.
Hi,
Since SharpCompress 0.41.0,
EntryStream.Dispose()callsFlush()on some internal decompression streams:This causes a
NotSupportedExceptionin some legitimate streaming scenarios.Context / real-world scenario
I'm using SharpCompress in a pure streaming pipeline in ASP.NET Core:
Source stream:
HttpRequest.BodyRead via MultipartReader (multipart/form-data)
Archive entries are processed sequentially using
ReaderFactory.Open(...).MoveToNextEntry()Entry streams are non-seekable by design
In this setup,
Flush()onDeflateStream/LzmaStreammay internally try to accessPosition/Seekon the underlying stream stack, which is not supported and throwsNotSupportedException.This happens during
EntryStream.Dispose(), which breaks the iteration and prevents moving to the next entry.Why this is problematic
From a consumer point of view:
Dispose()is expected to be safe and non-throwingEspecially in streaming scenarios,
Dispose()is required to advance to the next entryThrowing
NotSupportedExceptionduringDispose()makes SharpCompress unusable in valid non-seekable streaming pipelinesExpected behavior / suggestion
At minimum,
EntryStream.Dispose()should:Not throw if
Flush()is not supportedSwallow or ignore
NotSupportedExceptioncoming fromFlush()Example defensive pattern:
Or more generally:
Dispose()should never fail due to optional stream realignment logic.Workaround on consumer side
Currently I have to wrap
Dispose()with a try/catch and manually dispose the base stream viaIStreamStack, which works but feels like something the library should handle.Summary
The new
Flush()inEntryStream.Dispose()breaks valid non-seekable streaming scenarios.The over-read problem is real, but the current solution is unsafe.
Dispose()should not throw in this case.@adamhathcock commented on GitHub (Jan 22, 2026):
This should be easy to test, right? Use the ForwardOnlyStream on something with your same code? I have to confess I don't completely understand the scenario and why it's different from other streaming scenarios.
@adamhathcock commented on GitHub (Jan 22, 2026):
I think was done as requested
@rleroux-regnology commented on GitHub (Jan 23, 2026):
Thank you very much for the quick fix. I just retested with the latest changes and I no longer get errors when calling Dispose.
Unfortunately I'm still encountering issues when
ReaderFactoryconsumes myMultipartReaderStream.I have a silent issue when iterating through entries, I've created a new issue based on this: https://github.com/adamhathcock/sharpcompress/issues/1155