From 76de7d54c7eacf014d3fafc8352f61f3e32ef11d Mon Sep 17 00:00:00 2001 From: Nanook <188841+Nanook@users.noreply.github.com> Date: Fri, 1 Aug 2025 21:47:09 +0100 Subject: [PATCH 1/2] Rewind buffer fix for directory extract. --- src/SharpCompress/Archives/Zip/ZipArchive.cs | 2 +- .../Common/Zip/StreamingZipFilePart.cs | 1 - .../Common/Zip/StreamingZipHeaderFactory.cs | 13 ++++++++++++- tests/SharpCompress.Test/ArchiveTests.cs | 19 +++++++++++++++++++ tests/SharpCompress.Test/ReaderTests.cs | 2 +- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 4 ++++ 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/SharpCompress/Archives/Zip/ZipArchive.cs b/src/SharpCompress/Archives/Zip/ZipArchive.cs index d877626b7..a75b40954 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchive.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchive.cs @@ -330,7 +330,7 @@ bool closeStream protected override IReader CreateReaderForSolidExtraction() { var stream = Volumes.Single().Stream; - stream.Position = 0; + ((IStreamStack)stream).StackSeek(0); return ZipReader.Open(stream, ReaderOptions, Entries); } } diff --git a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs index 543d78d94..5464a9cc8 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs @@ -50,7 +50,6 @@ internal BinaryReader FixStreamedFileLocation(ref SharpCompressStream rewindable if (_decompressionStream is DeflateStream deflateStream) { ((IStreamStack)rewindableStream).StackSeek(0); - //rewindableStream.Rewind(deflateStream.InputBuffer); } Skipped = true; diff --git a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs index 723b59088..937c882bb 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs @@ -22,7 +22,18 @@ internal IEnumerable ReadStreamHeader(Stream stream) { if (stream is not SharpCompressStream) //ensure the stream is already a SharpCompressStream. So the buffer/size will already be set { - throw new ArgumentException("Stream must be a SharpCompressStream", nameof(stream)); + if (stream is SourceStream src) //the original code wrapped this with RewindableStream. Wrap with SharpCOmpressStream as we can get the boffer size + { + stream = new SharpCompressStream( + stream, + src.ReaderOptions.LeaveStreamOpen, + bufferSize: src.ReaderOptions.BufferSize + ); + } + else + { + throw new ArgumentException("Stream must be a SharpCompressStream", nameof(stream)); + } } SharpCompressStream rewindableStream = (SharpCompressStream)stream; diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 121d8dead..5a3d36ca5 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -252,6 +252,25 @@ IEnumerable testArchives } } + protected void ArchiveExtractToDirectory( + string testArchive, + ReaderOptions? readerOptions = null + ) => ArchiveExtractToDirectory(ArchiveFactory.AutoFactory, testArchive, readerOptions); + + protected void ArchiveExtractToDirectory( + IArchiveFactory archiveFactory, + string testArchive, + ReaderOptions? readerOptions = null + ) + { + testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive); + using (var archive = archiveFactory.Open(new FileInfo(testArchive), readerOptions)) + { + archive.ExtractToDirectory(SCRATCH_FILES_PATH); + } + VerifyFiles(); + } + protected void ArchiveFileRead( IArchiveFactory archiveFactory, string testArchive, diff --git a/tests/SharpCompress.Test/ReaderTests.cs b/tests/SharpCompress.Test/ReaderTests.cs index b43183487..0bc4dba9e 100644 --- a/tests/SharpCompress.Test/ReaderTests.cs +++ b/tests/SharpCompress.Test/ReaderTests.cs @@ -47,7 +47,7 @@ ReaderOptions options { UseReader(reader, expectedCompression); protectedStream.ThrowOnDispose = false; - Assert.False(testStream.IsDisposed, "{nameof(testStream)} prematurely closed"); + Assert.False(testStream.IsDisposed, $"{nameof(testStream)} prematurely closed"); } // Boolean XOR -- If the stream should be left open (true), then the stream should not be diposed (false) diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 58ebfa1c4..e09df7e96 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -88,6 +88,10 @@ public void WinZip26_X_Multi_ArchiveFileRead() => [Fact] public void Zip_Deflate_ArchiveFileRead() => ArchiveFileRead("Zip.deflate.zip"); + [Fact] + public void Zip_Deflate_ArchiveExtractToDirectory() => + ArchiveExtractToDirectory("Zip.deflate.zip"); + //will detect and load other files [Fact] public void Zip_Deflate_Multi_ArchiveFirstFileRead() => From 3abbb89c2e073e7052bd8d06912069fcf2199e19 Mon Sep 17 00:00:00 2001 From: Nanook <188841+Nanook@users.noreply.github.com> Date: Fri, 1 Aug 2025 21:50:36 +0100 Subject: [PATCH 2/2] Comment typo edit. --- src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs index 937c882bb..70b61bae2 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs @@ -22,7 +22,8 @@ internal IEnumerable ReadStreamHeader(Stream stream) { if (stream is not SharpCompressStream) //ensure the stream is already a SharpCompressStream. So the buffer/size will already be set { - if (stream is SourceStream src) //the original code wrapped this with RewindableStream. Wrap with SharpCOmpressStream as we can get the boffer size + //the original code wrapped this with RewindableStream. Wrap with SharpCompressStream as we can get the buffer size + if (stream is SourceStream src) { stream = new SharpCompressStream( stream,