diff --git a/src/SharpCompress/Common/EntryStream.cs b/src/SharpCompress/Common/EntryStream.cs index e4de4ca9..d265be00 100644 --- a/src/SharpCompress/Common/EntryStream.cs +++ b/src/SharpCompress/Common/EntryStream.cs @@ -79,11 +79,25 @@ public class EntryStream : Stream, IStreamStack { if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream) { - deflateStream.Flush(); //Deflate over reads. Knock it back + try + { + deflateStream.Flush(); //Deflate over reads. Knock it back + } + catch (NotSupportedException) + { + // Ignore: underlying stream does not support required operations for Flush + } } else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream) { - lzmaStream.Flush(); //Lzma over reads. Knock it back + try + { + lzmaStream.Flush(); //Lzma over reads. Knock it back + } + catch (NotSupportedException) + { + // Ignore: underlying stream does not support required operations for Flush + } } } #if DEBUG_STREAMS @@ -111,11 +125,25 @@ public class EntryStream : Stream, IStreamStack { if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream) { - await deflateStream.FlushAsync().ConfigureAwait(false); + try + { + await deflateStream.FlushAsync().ConfigureAwait(false); + } + catch (NotSupportedException) + { + // Ignore: underlying stream does not support required operations for Flush + } } else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream) { - await lzmaStream.FlushAsync().ConfigureAwait(false); + try + { + await lzmaStream.FlushAsync().ConfigureAwait(false); + } + catch (NotSupportedException) + { + // Ignore: underlying stream does not support required operations for Flush + } } } #if DEBUG_STREAMS diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index c3b53e11..0ad07ffb 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -444,4 +444,50 @@ public class ZipReaderTests : ReaderTests Assert.Equal(archiveKeys.OrderBy(k => k), readerKeys.OrderBy(k => k)); } } + + [Fact] + public void EntryStream_Dispose_DoesNotThrow_OnNonSeekableStream_Deflate() + { + // Test for issue: EntryStream.Dispose() should not throw NotSupportedException + // when Flush() fails on non-seekable streams (Deflate compression) + var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.dd.zip"); + using Stream stream = new ForwardOnlyStream(File.OpenRead(path)); + using var reader = ReaderFactory.OpenReader(stream); + + // This should not throw, even if internal Flush() fails + while (reader.MoveToNextEntry()) + { + if (!reader.Entry.IsDirectory) + { + using var entryStream = reader.OpenEntryStream(); + // Read some data + var buffer = new byte[1024]; + entryStream.Read(buffer, 0, buffer.Length); + // Dispose should not throw NotSupportedException + } + } + } + + [Fact] + public void EntryStream_Dispose_DoesNotThrow_OnNonSeekableStream_LZMA() + { + // Test for issue: EntryStream.Dispose() should not throw NotSupportedException + // when Flush() fails on non-seekable streams (LZMA compression) + var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.dd.zip"); + using Stream stream = new ForwardOnlyStream(File.OpenRead(path)); + using var reader = ReaderFactory.OpenReader(stream); + + // This should not throw, even if internal Flush() fails + while (reader.MoveToNextEntry()) + { + if (!reader.Entry.IsDirectory) + { + using var entryStream = reader.OpenEntryStream(); + // Read some data + var buffer = new byte[1024]; + entryStream.Read(buffer, 0, buffer.Length); + // Dispose should not throw NotSupportedException + } + } + } }