From 8b55cce39a5e1110283e1110e2616348b2e74dfd Mon Sep 17 00:00:00 2001 From: Martin Demberger Date: Wed, 15 Jun 2022 16:28:14 +0200 Subject: [PATCH 01/21] Better handling of uncompressed zip files. --- src/SharpCompress/IO/RewindableStream.cs | 10 ++-- src/SharpCompress/IO/SourceStream.cs | 3 +- tests/SharpCompress.Test/ArchiveTests.cs | 47 +++++++++++------- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 12 +++++ .../Archives/Zip.uncompressed.zip | Bin 0 -> 544 bytes 5 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 tests/TestArchives/Archives/Zip.uncompressed.zip diff --git a/src/SharpCompress/IO/RewindableStream.cs b/src/SharpCompress/IO/RewindableStream.cs index e609fbab..fc430aae 100644 --- a/src/SharpCompress/IO/RewindableStream.cs +++ b/src/SharpCompress/IO/RewindableStream.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace SharpCompress.IO @@ -119,8 +119,10 @@ namespace SharpCompress.IO int read; if (isRewound && bufferStream.Position != bufferStream.Length) { - read = bufferStream.Read(buffer, offset, count); - if (read < count) + // don't read more than left + int readCount = Math.Min(count, (int)(bufferStream.Length - bufferStream.Position)); + read = bufferStream.Read(buffer, offset, readCount); + if (read < readCount) { int tempRead = stream.Read(buffer, offset + read, count - read); if (IsRecording) @@ -160,4 +162,4 @@ namespace SharpCompress.IO throw new NotSupportedException(); } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/IO/SourceStream.cs b/src/SharpCompress/IO/SourceStream.cs index c13c0269..71918c81 100644 --- a/src/SharpCompress/IO/SourceStream.cs +++ b/src/SharpCompress/IO/SourceStream.cs @@ -144,7 +144,8 @@ namespace SharpCompress.IO if (!IsVolumes && count != 0 && Current.Position == Current.Length) { _prevSize += Current.Length; - SetStream(_stream + 1); //will load next file + if (!SetStream(_stream + 1)) //will load next file if present + break; Current.Seek(0, SeekOrigin.Begin); } } diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 0bf586e9..25249fb1 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -33,30 +33,41 @@ namespace SharpCompress.Test foreach (var path in testArchives) { using (var stream = new NonDisposingStream(File.OpenRead(path), true)) - using (var archive = ArchiveFactory.Open(stream)) { - Assert.True(archive.IsSolid); - using (var reader = archive.ExtractAllEntries()) + try { - UseReader(reader, compression); - } - VerifyFiles(); + using (var archive = ArchiveFactory.Open(stream)) + { + Assert.True(archive.IsSolid); + using (var reader = archive.ExtractAllEntries()) + { + UseReader(reader, compression); + } + VerifyFiles(); - if (archive.Entries.First().CompressionType == CompressionType.Rar) + if (archive.Entries.First().CompressionType == CompressionType.Rar) + { + stream.ThrowOnDispose = false; + return; + } + foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) + { + entry.WriteToDirectory(SCRATCH_FILES_PATH, + new ExtractionOptions + { + ExtractFullPath = true, + Overwrite = true + }); + } + stream.ThrowOnDispose = false; + } + } + catch (Exception) { + // Otherwise this will hide the original exception. stream.ThrowOnDispose = false; - return; + throw; } - foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) - { - entry.WriteToDirectory(SCRATCH_FILES_PATH, - new ExtractionOptions - { - ExtractFullPath = true, - Overwrite = true - }); - } - stream.ThrowOnDispose = false; } VerifyFiles(); } diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 0fc9d168..3352bf0e 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -713,5 +713,17 @@ namespace SharpCompress.Test.Zip } } + [Fact] + public void Zip_Uncompressed_Skip_All() + { + string zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip"); + using (var stream = File.Open(zipPath, FileMode.Open, FileAccess.Read)) + { + IArchive archive = ArchiveFactory.Open(stream); + IReader reader = archive.ExtractAllEntries(); + while (reader.MoveToNextEntry()) + ; + } + } } } diff --git a/tests/TestArchives/Archives/Zip.uncompressed.zip b/tests/TestArchives/Archives/Zip.uncompressed.zip new file mode 100644 index 0000000000000000000000000000000000000000..9b9aea6d5f5d8528be9062f0dc2fa4f418e9a6e5 GIT binary patch literal 544 zcmWIWW@Zs#;NW0jP^eS$XFvi13=9lz`8g@6Mfz@;IjM$vB^4zhsl_Em0p9E!F^j4$ zu`)0)fH2WU80i(2q*cchm82Qgf(&`KYV&D!1_lNY#%+io+#N<_I|SVfBbaAQK<>z7 zm$U|X1cU>;8JR>F5Fvu>QBa5=1rXd_2xp<|M)o19Zf8{8;GjX*jchl_2MD`6;JT5* j1YJ9_w@|g8LDLQnjsR~~HjoW03@i-47#J7?7(qM$x!+yp literal 0 HcmV?d00001 From b6c4e28b4d393f08970919047e6ed8c5bff7054e Mon Sep 17 00:00:00 2001 From: Lars Vahlenberg Date: Thu, 16 Jun 2022 23:32:46 +0200 Subject: [PATCH 02/21] Generated test case, however, don't see any problems --- .../SharpCompress.Test/Zip/ZipWriterTests.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/SharpCompress.Test/Zip/ZipWriterTests.cs b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs index 2c70e416..6c997515 100644 --- a/tests/SharpCompress.Test/Zip/ZipWriterTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs @@ -1,7 +1,10 @@ -using System.Text; +using System.Text; using SharpCompress.Common; using Xunit; +using System.IO; +using SharpCompress.Writers.Zip; +using SharpCompress.Compressors.Deflate; namespace SharpCompress.Test.Zip { @@ -49,5 +52,23 @@ namespace SharpCompress.Test.Zip { Assert.Throws(() => Write(CompressionType.Rar, "Zip.ppmd.noEmptyDirs.zip", "Zip.ppmd.noEmptyDirs.zip")); } + + [Fact] + public void Zip_Write_MemoryStream() + { + var ms = new MemoryStream(); + var zw = new ZipWriter(ms, new ZipWriterOptions(compressionType: CompressionType.Deflate ) { DeflateCompressionLevel = CompressionLevel.None } ); + var payload = new string('\n', 100000); + using (var stream = zw.WriteToStream("test.txt", new ZipWriterEntryOptions())) + using (var streamWriter = new StreamWriter(stream: stream)) + { + streamWriter.Write(payload); + } + + using( var file = new FileStream("d:\\projects\\test.zip", FileMode.Create, FileAccess.Write)) + { + ms.WriteTo(file); + } + } } } From a00075ee0d3a712c4aa4cdb44c7a4f19eb7f8b6a Mon Sep 17 00:00:00 2001 From: Lars Vahlenberg Date: Fri, 17 Jun 2022 15:07:07 +0200 Subject: [PATCH 03/21] Wrong flags set, we do not expose this in the interface --- .../Writers/Zip/ZipCentralDirectoryEntry.cs | 24 +++++++++++++++---- .../SharpCompress.Test/Zip/ZipWriterTests.cs | 21 ---------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs index 8fe87d1e..d4609ef6 100644 --- a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs +++ b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.IO; using System.Text; @@ -98,10 +98,24 @@ namespace SharpCompress.Writers.Zip BinaryPrimitives.WriteUInt16LittleEndian(intBuf, 0); outputStream.Write(intBuf.Slice(0, 2)); // disk=0 - BinaryPrimitives.WriteUInt16LittleEndian(intBuf, (ushort)flags); - outputStream.Write(intBuf.Slice(0, 2)); // file type: binary - BinaryPrimitives.WriteUInt16LittleEndian(intBuf, (ushort)flags); - outputStream.Write(intBuf.Slice(0, 2)); // Internal file attributes + + // Internal file attributes: + // Bit 0: apparent ASCII/ text file + // Bit 1: reserved + // Bit 2: control field records precede logical records + // Bits 3 - 16: unused + BinaryPrimitives.WriteUInt16LittleEndian(intBuf, 0); + outputStream.Write(intBuf.Slice(0, 2)); // file type: binary, Internal file attributes + + // External flags are host-dependent, this might match DOS + // Bit 0: Read-Only + // Bit 1: Hidden + // Bit 2: System + // Bit 3: Label + // Bit 4: Directory + // Bit 5: Archive + BinaryPrimitives.WriteUInt16LittleEndian(intBuf, 0); + outputStream.Write(intBuf.Slice(0, 2)); // External file attributes BinaryPrimitives.WriteUInt16LittleEndian(intBuf, 0x8100); outputStream.Write(intBuf.Slice(0, 2)); diff --git a/tests/SharpCompress.Test/Zip/ZipWriterTests.cs b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs index 6c997515..8d546cec 100644 --- a/tests/SharpCompress.Test/Zip/ZipWriterTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs @@ -2,9 +2,6 @@ using System.Text; using SharpCompress.Common; using Xunit; -using System.IO; -using SharpCompress.Writers.Zip; -using SharpCompress.Compressors.Deflate; namespace SharpCompress.Test.Zip { @@ -52,23 +49,5 @@ namespace SharpCompress.Test.Zip { Assert.Throws(() => Write(CompressionType.Rar, "Zip.ppmd.noEmptyDirs.zip", "Zip.ppmd.noEmptyDirs.zip")); } - - [Fact] - public void Zip_Write_MemoryStream() - { - var ms = new MemoryStream(); - var zw = new ZipWriter(ms, new ZipWriterOptions(compressionType: CompressionType.Deflate ) { DeflateCompressionLevel = CompressionLevel.None } ); - var payload = new string('\n', 100000); - using (var stream = zw.WriteToStream("test.txt", new ZipWriterEntryOptions())) - using (var streamWriter = new StreamWriter(stream: stream)) - { - streamWriter.Write(payload); - } - - using( var file = new FileStream("d:\\projects\\test.zip", FileMode.Create, FileAccess.Write)) - { - ms.WriteTo(file); - } - } } } From ece7cbfec3297b6cb0edbba195aac7e49a6179ad Mon Sep 17 00:00:00 2001 From: Martin Demberger Date: Sat, 18 Jun 2022 14:35:14 +0200 Subject: [PATCH 04/21] Set skip-marker when stream is skipped --- src/SharpCompress/Readers/AbstractReader.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index fe6285ff..80e6cf07 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -131,26 +131,27 @@ namespace SharpCompress.Readers private void Skip() { + var part = Entry.Parts.First(); + part.Skipped = true; + if (ArchiveType != ArchiveType.Rar && !Entry.IsSolid && Entry.CompressedSize > 0) { //not solid and has a known compressed size then we can skip raw bytes. - var part = Entry.Parts.First(); var rawStream = part.GetRawStream(); if (rawStream != null) { var bytesToAdvance = Entry.CompressedSize; rawStream.Skip(bytesToAdvance); - part.Skipped = true; return; } } //don't know the size so we have to try to decompress to skip using (var s = OpenEntryStream()) { - s.Skip(); + s.SkipEntry(); } } From 35336a0827a77417ec52f9a650302c95181b89b8 Mon Sep 17 00:00:00 2001 From: Martin Demberger Date: Sun, 19 Jun 2022 22:05:52 +0200 Subject: [PATCH 05/21] Suppress nested NonDisposingStream --- .../Archives/GZip/GZipWritableArchiveEntry.cs | 6 +++--- .../Archives/Tar/TarWritableArchiveEntry.cs | 6 +++--- .../Archives/Zip/ZipWritableArchiveEntry.cs | 6 +++--- src/SharpCompress/Common/Volume.cs | 6 +++--- .../Common/Zip/StreamingZipFilePart.cs | 6 +++--- src/SharpCompress/Common/Zip/ZipFilePart.cs | 6 +++--- src/SharpCompress/Compressors/Xz/XZFooter.cs | 4 ++-- src/SharpCompress/Compressors/Xz/XZHeader.cs | 4 ++-- src/SharpCompress/Compressors/Xz/XZIndex.cs | 4 ++-- src/SharpCompress/IO/NonDisposingStream.cs | 13 +++++++++++-- src/SharpCompress/Readers/ReaderFactory.cs | 6 +++--- src/SharpCompress/Writers/GZip/GZipWriter.cs | 6 +++--- src/SharpCompress/Writers/Tar/TarWriter.cs | 4 ++-- src/SharpCompress/Writers/Zip/ZipWriter.cs | 4 ++-- tests/SharpCompress.Test/ArchiveTests.cs | 4 ++-- tests/SharpCompress.Test/ReaderTests.cs | 4 ++-- .../Streams/ZlibBaseStreamTests.cs | 4 ++-- tests/SharpCompress.Test/WriterTests.cs | 4 ++-- tests/SharpCompress.Test/Zip/ZipReaderTests.cs | 2 +- 19 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs index 620d0802..4a315571 100644 --- a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable using System; using System.Collections.Generic; @@ -54,7 +54,7 @@ namespace SharpCompress.Archives.GZip { //ensure new stream is at the start, this could be reset stream.Seek(0, SeekOrigin.Begin); - return new NonDisposingStream(stream); + return NonDisposingStream.Create(stream); } internal override void Close() @@ -65,4 +65,4 @@ namespace SharpCompress.Archives.GZip } } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs index a776b44b..1f96ca3d 100644 --- a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable using System; using System.Collections.Generic; @@ -53,7 +53,7 @@ namespace SharpCompress.Archives.Tar { //ensure new stream is at the start, this could be reset stream.Seek(0, SeekOrigin.Begin); - return new NonDisposingStream(stream); + return NonDisposingStream.Create(stream); } internal override void Close() @@ -64,4 +64,4 @@ namespace SharpCompress.Archives.Tar } } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs index 4cd1fe61..7a91993a 100644 --- a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using SharpCompress.Common; @@ -53,7 +53,7 @@ namespace SharpCompress.Archives.Zip { //ensure new stream is at the start, this could be reset stream.Seek(0, SeekOrigin.Begin); - return new NonDisposingStream(stream); + return NonDisposingStream.Create(stream); } internal override void Close() @@ -65,4 +65,4 @@ namespace SharpCompress.Archives.Zip } } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Volume.cs b/src/SharpCompress/Common/Volume.cs index b937b281..f1b93d02 100644 --- a/src/SharpCompress/Common/Volume.cs +++ b/src/SharpCompress/Common/Volume.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using SharpCompress.IO; using SharpCompress.Readers; @@ -14,7 +14,7 @@ namespace SharpCompress.Common ReaderOptions = readerOptions; if (readerOptions.LeaveStreamOpen) { - stream = new NonDisposingStream(stream); + stream = NonDisposingStream.Create(stream); } _actualStream = stream; } @@ -48,4 +48,4 @@ namespace SharpCompress.Common GC.SuppressFinalize(this); } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs index f94413f9..fbffe179 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using SharpCompress.Common.Zip.Headers; using SharpCompress.Compressors.Deflate; using SharpCompress.IO; @@ -28,7 +28,7 @@ namespace SharpCompress.Common.Zip _decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream()), Header.CompressionMethod); if (LeaveStreamOpen) { - return new NonDisposingStream(_decompressionStream); + return NonDisposingStream.Create(_decompressionStream); } return _decompressionStream; } @@ -56,4 +56,4 @@ namespace SharpCompress.Common.Zip return reader; } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs index 937c1a8f..5fd6c4ac 100644 --- a/src/SharpCompress/Common/Zip/ZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.IO; using System.Linq; @@ -37,7 +37,7 @@ namespace SharpCompress.Common.Zip Stream decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream()), Header.CompressionMethod); if (LeaveStreamOpen) { - return new NonDisposingStream(decompressionStream); + return NonDisposingStream.Create(decompressionStream); } return decompressionStream; } @@ -142,7 +142,7 @@ namespace SharpCompress.Common.Zip && FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor)) || Header.IsZip64) { - plainStream = new NonDisposingStream(plainStream); //make sure AES doesn't close + plainStream = NonDisposingStream.Create(plainStream); //make sure AES doesn't close } else { diff --git a/src/SharpCompress/Compressors/Xz/XZFooter.cs b/src/SharpCompress/Compressors/Xz/XZFooter.cs index 3d070fe6..52f72619 100644 --- a/src/SharpCompress/Compressors/Xz/XZFooter.cs +++ b/src/SharpCompress/Compressors/Xz/XZFooter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Text; @@ -22,7 +22,7 @@ namespace SharpCompress.Compressors.Xz public static XZFooter FromStream(Stream stream) { - var footer = new XZFooter(new BinaryReader(new NonDisposingStream(stream), Encoding.UTF8)); + var footer = new XZFooter(new BinaryReader(NonDisposingStream.Create(stream), Encoding.UTF8)); footer.Process(); return footer; } diff --git a/src/SharpCompress/Compressors/Xz/XZHeader.cs b/src/SharpCompress/Compressors/Xz/XZHeader.cs index 587f20da..8934e135 100644 --- a/src/SharpCompress/Compressors/Xz/XZHeader.cs +++ b/src/SharpCompress/Compressors/Xz/XZHeader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Text; @@ -21,7 +21,7 @@ namespace SharpCompress.Compressors.Xz public static XZHeader FromStream(Stream stream) { - var header = new XZHeader(new BinaryReader(new NonDisposingStream(stream), Encoding.UTF8)); + var header = new XZHeader(new BinaryReader(NonDisposingStream.Create(stream), Encoding.UTF8)); header.Process(); return header; } diff --git a/src/SharpCompress/Compressors/Xz/XZIndex.cs b/src/SharpCompress/Compressors/Xz/XZIndex.cs index d634db0c..997d53c3 100644 --- a/src/SharpCompress/Compressors/Xz/XZIndex.cs +++ b/src/SharpCompress/Compressors/Xz/XZIndex.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -30,7 +30,7 @@ namespace SharpCompress.Compressors.Xz public static XZIndex FromStream(Stream stream, bool indexMarkerAlreadyVerified) { - var index = new XZIndex(new BinaryReader(new NonDisposingStream(stream), Encoding.UTF8), indexMarkerAlreadyVerified); + var index = new XZIndex(new BinaryReader(NonDisposingStream.Create(stream), Encoding.UTF8), indexMarkerAlreadyVerified); index.Process(); return index; } diff --git a/src/SharpCompress/IO/NonDisposingStream.cs b/src/SharpCompress/IO/NonDisposingStream.cs index 9b326c99..12b9a6cf 100644 --- a/src/SharpCompress/IO/NonDisposingStream.cs +++ b/src/SharpCompress/IO/NonDisposingStream.cs @@ -1,11 +1,20 @@ -using System; +using System; using System.IO; namespace SharpCompress.IO { public class NonDisposingStream : Stream { - public NonDisposingStream(Stream stream, bool throwOnDispose = false) + public static NonDisposingStream Create(Stream stream, bool throwOnDispose = false) + { + if (stream is NonDisposingStream nonDisposingStream && nonDisposingStream.ThrowOnDispose == throwOnDispose) + { + return nonDisposingStream; + } + return new NonDisposingStream(stream, throwOnDispose); + } + + protected NonDisposingStream(Stream stream, bool throwOnDispose = false) { Stream = stream; ThrowOnDispose = throwOnDispose; diff --git a/src/SharpCompress/Readers/ReaderFactory.cs b/src/SharpCompress/Readers/ReaderFactory.cs index 1384264f..adff51cc 100644 --- a/src/SharpCompress/Readers/ReaderFactory.cs +++ b/src/SharpCompress/Readers/ReaderFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using SharpCompress.Archives.GZip; using SharpCompress.Archives.Rar; @@ -58,7 +58,7 @@ namespace SharpCompress.Readers if (BZip2Stream.IsBZip2(rewindableStream)) { rewindableStream.Rewind(false); - BZip2Stream testStream = new BZip2Stream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress, false); + BZip2Stream testStream = new BZip2Stream(NonDisposingStream.Create(rewindableStream), CompressionMode.Decompress, false); if (TarArchive.IsTarFile(testStream)) { rewindableStream.Rewind(true); @@ -70,7 +70,7 @@ namespace SharpCompress.Readers if (LZipStream.IsLZipFile(rewindableStream)) { rewindableStream.Rewind(false); - LZipStream testStream = new LZipStream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress); + LZipStream testStream = new LZipStream(NonDisposingStream.Create(rewindableStream), CompressionMode.Decompress); if (TarArchive.IsTarFile(testStream)) { rewindableStream.Rewind(true); diff --git a/src/SharpCompress/Writers/GZip/GZipWriter.cs b/src/SharpCompress/Writers/GZip/GZipWriter.cs index 1147b686..12e820a2 100644 --- a/src/SharpCompress/Writers/GZip/GZipWriter.cs +++ b/src/SharpCompress/Writers/GZip/GZipWriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using SharpCompress.Common; using SharpCompress.Compressors; @@ -16,7 +16,7 @@ namespace SharpCompress.Writers.GZip { if (WriterOptions.LeaveStreamOpen) { - destination = new NonDisposingStream(destination); + destination = NonDisposingStream.Create(destination); } InitalizeStream(new GZipStream(destination, CompressionMode.Compress, options?.CompressionLevel ?? CompressionLevel.Default, @@ -46,4 +46,4 @@ namespace SharpCompress.Writers.GZip _wroteToStream = true; } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Writers/Tar/TarWriter.cs b/src/SharpCompress/Writers/Tar/TarWriter.cs index d78e8692..c90e069e 100644 --- a/src/SharpCompress/Writers/Tar/TarWriter.cs +++ b/src/SharpCompress/Writers/Tar/TarWriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using SharpCompress.Common; using SharpCompress.Common.Tar.Headers; @@ -25,7 +25,7 @@ namespace SharpCompress.Writers.Tar } if (WriterOptions.LeaveStreamOpen) { - destination = new NonDisposingStream(destination); + destination = NonDisposingStream.Create(destination); } switch (options.CompressionType) { diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index c726c4fb..7ee74e19 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.Collections.Generic; using System.IO; @@ -40,7 +40,7 @@ namespace SharpCompress.Writers.Zip if (WriterOptions.LeaveStreamOpen) { - destination = new NonDisposingStream(destination); + destination = NonDisposingStream.Create(destination); } InitalizeStream(destination); } diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 0bf586e9..bbd16663 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -32,7 +32,7 @@ namespace SharpCompress.Test { foreach (var path in testArchives) { - using (var stream = new NonDisposingStream(File.OpenRead(path), true)) + using (var stream = NonDisposingStream.Create(File.OpenRead(path), true)) using (var archive = ArchiveFactory.Open(stream)) { Assert.True(archive.IsSolid); @@ -77,7 +77,7 @@ namespace SharpCompress.Test { foreach (var path in testArchives) { - using (var stream = new NonDisposingStream(File.OpenRead(path), true)) + using (var stream = NonDisposingStream.Create(File.OpenRead(path), true)) using (var archive = ArchiveFactory.Open(stream, readerOptions)) { try diff --git a/tests/SharpCompress.Test/ReaderTests.cs b/tests/SharpCompress.Test/ReaderTests.cs index 82ca6d29..d5cfd9dd 100644 --- a/tests/SharpCompress.Test/ReaderTests.cs +++ b/tests/SharpCompress.Test/ReaderTests.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using SharpCompress.Common; using SharpCompress.IO; using SharpCompress.Readers; @@ -27,7 +27,7 @@ namespace SharpCompress.Test { using (var file = File.OpenRead(testArchive)) { - using (var protectedStream = new NonDisposingStream(new ForwardOnlyStream(file), throwOnDispose: true)) + using (var protectedStream = NonDisposingStream.Create(new ForwardOnlyStream(file), throwOnDispose: true)) { using (var testStream = new TestStream(protectedStream)) { diff --git a/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs b/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs index c8d55283..51d2085b 100644 --- a/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs +++ b/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs @@ -63,7 +63,7 @@ namespace SharpCompress.Test.Streams private void Compress(Stream input, Stream output, int compressionLevel) { - using (var zlibStream = new ZlibStream(new NonDisposingStream(output), CompressionMode.Compress, (CompressionLevel)compressionLevel)) + using (var zlibStream = new ZlibStream(NonDisposingStream.Create(output), CompressionMode.Compress, (CompressionLevel)compressionLevel)) { zlibStream.FlushMode = FlushType.Sync; input.CopyTo(zlibStream); @@ -72,7 +72,7 @@ namespace SharpCompress.Test.Streams private void Decompress(Stream input, Stream output) { - using (var zlibStream = new ZlibStream(new NonDisposingStream(input), CompressionMode.Decompress)) + using (var zlibStream = new ZlibStream(NonDisposingStream.Create(input), CompressionMode.Decompress)) { zlibStream.CopyTo(output); } diff --git a/tests/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs index 2d99325d..53c66307 100644 --- a/tests/SharpCompress.Test/WriterTests.cs +++ b/tests/SharpCompress.Test/WriterTests.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Text; using SharpCompress.Common; using SharpCompress.IO; @@ -41,7 +41,7 @@ namespace SharpCompress.Test readerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default; - using (var reader = ReaderFactory.Open(new NonDisposingStream(stream), readerOptions)) + using (var reader = ReaderFactory.Open(NonDisposingStream.Create(stream), readerOptions)) { reader.WriteAllToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index c7eb3c41..d2b23877 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -319,7 +319,7 @@ namespace SharpCompress.Test.Zip stream = new MemoryStream(memory.ToArray()); File.WriteAllBytes(Path.Combine(SCRATCH_FILES_PATH, "foo.zip"), memory.ToArray()); - using (IReader zipReader = ZipReader.Open(new NonDisposingStream(stream, true))) + using (IReader zipReader = ZipReader.Open(NonDisposingStream.Create(stream, true))) { var i = 0; while (zipReader.MoveToNextEntry()) From c0e43cc0e59d2459207673203c00f0ca6c229dbe Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 20 Jun 2022 10:32:47 +0100 Subject: [PATCH 06/21] Mark for 0.32.1 --- src/SharpCompress/SharpCompress.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 91491faa..f35bf43f 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -2,9 +2,9 @@ SharpCompress - Pure C# Decompression/Compression en-US - 0.32.0 - 0.32.0 - 0.32.0 + 0.32.1 + 0.32.1 + 0.32.1 Adam Hathcock net461;netstandard2.0;netstandard2.1;netcoreapp3.1;net6.0 true From 089b16326e9202e644fcfe0a85a2752e19769c10 Mon Sep 17 00:00:00 2001 From: Lars Vahlenberg Date: Tue, 21 Jun 2022 19:30:07 +0200 Subject: [PATCH 07/21] ReadOnlySubStream overrides and adds logic to Read byte[], needs to have same logic for Span for consistency. --- src/SharpCompress/IO/ReadOnlySubStream.cs | 17 ++++++++++++-- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 22 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/SharpCompress/IO/ReadOnlySubStream.cs b/src/SharpCompress/IO/ReadOnlySubStream.cs index e05921ca..4ba326dd 100644 --- a/src/SharpCompress/IO/ReadOnlySubStream.cs +++ b/src/SharpCompress/IO/ReadOnlySubStream.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace SharpCompress.IO @@ -65,6 +65,19 @@ namespace SharpCompress.IO return value; } +#if !NETFRAMEWORK && !NETSTANDARD2_0 + public override int Read(Span buffer) + { + var slice_len = BytesLeftToRead < buffer.Length ? BytesLeftToRead : buffer.Length; + var read = Stream.Read(buffer.Slice(0,(int)slice_len)); + if (read > 0) + { + BytesLeftToRead -= read; + } + return read; + } +#endif + public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); @@ -80,4 +93,4 @@ namespace SharpCompress.IO throw new NotSupportedException(); } } -} \ No newline at end of file +} diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 0fc9d168..5426d20d 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -680,6 +680,28 @@ namespace SharpCompress.Test.Zip firstStream.CopyTo(memoryStream); Assert.Equal(199, memoryStream.Length); } + + var len1 = 0; + var buffer1 = new byte[firstEntry.Size + 256]; + + using (var firstStream = firstEntry.OpenEntryStream()) + { + len1 = firstStream.Read(buffer1, 0, buffer.Length); + } + + Assert.Equal(199, len1); + +#if !NETFRAMEWORK && !NETSTANDARD2_0 + var len2 = 0; + var buffer2 = new byte[firstEntry.Size + 256]; + + using (var firstStream = firstEntry.OpenEntryStream()) + { + len2 = firstStream.Read(buffer2.AsSpan()); + } + Assert.Equal(len1, len2); + Assert.Equal(buffer1, buffer2); +#endif } } From d4c7551087c4bd30ba3e906017983db6fd59e89c Mon Sep 17 00:00:00 2001 From: louis-michel Date: Mon, 27 Jun 2022 19:13:10 -0400 Subject: [PATCH 08/21] Fix LZMA Code function --- .../Compressors/LZMA/LzmaDecoder.cs | 10 +-- .../Streams/LzmaStreamTests.cs | 74 +++++++++++++++++-- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs b/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs index 3592cfbf..ee595e68 100644 --- a/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs +++ b/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs @@ -297,14 +297,6 @@ namespace SharpCompress.Compressors.LZMA _outWindow.ReleaseStream(); rangeDecoder.ReleaseStream(); - if (!rangeDecoder.IsFinished || (inSize > 0 && rangeDecoder._total != inSize)) - { - throw new DataErrorException(); - } - if (_outWindow.HasPending) - { - throw new DataErrorException(); - } _outWindow = null; } @@ -480,4 +472,4 @@ namespace SharpCompress.Compressors.LZMA public override void SetLength(long value) {} */ } -} \ No newline at end of file +} diff --git a/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs b/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs index 3e41ee83..fd14be48 100644 --- a/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs +++ b/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs @@ -1,4 +1,6 @@ -using System.IO; + +using System; +using System.IO; using SharpCompress.Compressors.LZMA; using Xunit; @@ -9,12 +11,72 @@ namespace SharpCompress.Test.Streams [Fact] public void TestLzma2Decompress1Byte() { - byte[] properties = new byte[] { 0x01 }; - byte[] compressedData = new byte[] { 0x01, 0x00, 0x00, 0x58, 0x00 }; - MemoryStream lzma2Stream = new MemoryStream(compressedData); + var properties = new byte[] { 0x01 }; + var compressedData = new byte[] { 0x01, 0x00, 0x00, 0x58, 0x00 }; + var lzma2Stream = new MemoryStream(compressedData); - LzmaStream decompressor = new LzmaStream(properties, lzma2Stream, 5, 1); + var decompressor = new LzmaStream(properties, lzma2Stream, 5, 1); Assert.Equal('X', decompressor.ReadByte()); } + + private static byte[] lzmaData { get; } = new byte[] { + 0x5D, 0x00, 0x20, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x24, 0x18, 0x2F, 0xEB, 0x20, 0x78, 0xBA, 0x78, 0x70, 0xDC, 0x43, 0x2C, 0x32, 0xC9, + 0xC3, 0x97, 0x4D, 0x10, 0x74, 0xE2, 0x20, 0xBF, 0x5A, 0xB4, 0xB3, 0xC4, 0x31, 0x80, 0x26, + 0x3E, 0x6A, 0xEA, 0x51, 0xFC, 0xE4, 0x8D, 0x54, 0x96, 0x05, 0xCC, 0x78, 0x59, 0xAC, 0xD4, + 0x21, 0x65, 0x8F, 0xA9, 0xC8, 0x0D, 0x9B, 0xE2, 0xC2, 0xF9, 0x7C, 0x3C, 0xDD, 0x4D, 0x38, + 0x04, 0x0B, 0xF8, 0x0B, 0x68, 0xA5, 0x93, 0x6C, 0x64, 0xAC, 0xCF, 0x71, 0x68, 0xE8, 0x69, + 0x25, 0xC6, 0x17, 0x28, 0xF1, 0x7C, 0xF1, 0xDC, 0x47, 0x51, 0x4D, 0x1E, 0x0E, 0x0B, 0x80, + 0x37, 0x24, 0x58, 0x80, 0xF7, 0xB4, 0xAC, 0x54, 0xF1, 0x0F, 0x7F, 0x0F, 0x0F, 0xF5, 0x9C, + 0xDE, 0x54, 0x4F, 0xA3, 0x7B, 0x20, 0xC5, 0xA8, 0x18, 0x3B, 0xED, 0xDC, 0x04, 0xF6, 0xFB, + 0x86, 0xE0, 0xAB, 0xB6, 0x87, 0x99, 0x92, 0x43, 0x7B, 0x2C, 0xCC, 0x31, 0x83, 0x90, 0xFF, + 0xF1, 0x76, 0x03, 0x90 + }; + + private static byte[] lzmaResultData { get; } = new byte[] { + 0x01, 0x00, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x61, 0x18, 0x5F, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x00, 0xB4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x61, 0xE5, 0x5E, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0xB4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x61, 0x18, + 0x5F, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x18, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0xB4, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0x61, 0xE5, 0x5E, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0xCB, 0x15, 0x00, 0x00, 0x02, 0x00, 0xB4, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0x61, 0xE5, 0x5E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0xCB, 0x15, 0x00, 0x00, 0x02, 0x00, 0xB4, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x61, 0xE5, 0x5E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, + 0x00, 0xB4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x96, 0x40, 0x5C, 0x08, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x83, 0x12, + 0x00, 0xD4, 0x99, 0x00, 0x00, 0x43, 0x95, 0x00, 0x00, 0xEB, 0x7A, 0x00, 0x00, 0x40, 0x6F, + 0x00, 0x00, 0xD2, 0x6F, 0x00, 0x00, 0x67, 0x74, 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x76, + 0x79, 0x00, 0x00, 0x98, 0x66, 0x00, 0x00, 0x23, 0x25, 0x00, 0x00, 0x01, 0x00, 0xFD, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x3B, 0x2F, 0xC0, 0x5F, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x00, 0x3D, 0x00, 0x0A, 0x00, 0x00, 0x00 + }; + + [Fact] + public void TestLzmaBuffer() + { + var input = new MemoryStream(lzmaData); + using (var output = new MemoryStream()) + { + var properties = new byte[5]; + input.Read(properties, 0, 5); + + var fileLengthBytes = new byte[8]; + input.Read(fileLengthBytes, 0, 8); + var fileLength = BitConverter.ToInt64(fileLengthBytes, 0); + + var coder = new Decoder(); + coder.SetDecoderProperties(properties); + coder.Code(input, output, input.Length, fileLength, null); + + Assert.Equal(output.ToArray(), lzmaResultData); + } + } } -} \ No newline at end of file +} From 4eb1fe0b8043a68256dc60beb4a9c9828910998a Mon Sep 17 00:00:00 2001 From: Nanook Date: Fri, 15 Jul 2022 21:15:10 +0100 Subject: [PATCH 09/21] RarArchive has Min/MaxVersion. RarEntry has Volumne Indexes. GZ CRC fix. --- .../Archives/GZip/GZipArchive.cs | 3 +- .../Archives/Rar/FileInfoRarArchiveVolume.cs | 6 +- .../Archives/Rar/FileInfoRarFilePart.cs | 4 +- src/SharpCompress/Archives/Rar/RarArchive.cs | 8 ++- .../Archives/Rar/RarArchiveEntry.cs | 2 +- .../Archives/Rar/SeekableFilePart.cs | 8 +-- .../Archives/Rar/StreamRarArchiveVolume.cs | 10 ++-- .../Archives/SevenZip/SevenZipArchive.cs | 3 +- src/SharpCompress/Archives/Tar/TarArchive.cs | 3 +- src/SharpCompress/Archives/Zip/ZipArchive.cs | 5 +- src/SharpCompress/Common/Entry.cs | 5 +- src/SharpCompress/Common/FilePart.cs | 3 +- src/SharpCompress/Common/GZip/GZipFilePart.cs | 10 ++-- src/SharpCompress/Common/GZip/GZipVolume.cs | 8 +-- src/SharpCompress/Common/IEntry.cs | 7 ++- src/SharpCompress/Common/IVolume.cs | 7 ++- src/SharpCompress/Common/Rar/RarFilePart.cs | 7 ++- src/SharpCompress/Common/Rar/RarVolume.cs | 43 +++++++++++++-- .../Common/SevenZip/SevenZipFilePart.cs | 5 +- .../Common/SevenZip/SevenZipVolume.cs | 8 +-- src/SharpCompress/Common/Tar/TarVolume.cs | 8 +-- src/SharpCompress/Common/Volume.cs | 7 ++- src/SharpCompress/Common/Zip/ZipVolume.cs | 8 +-- .../Readers/Rar/NonSeekableStreamFilePart.cs | 8 +-- .../Readers/Rar/RarReaderVolume.cs | 10 ++-- tests/SharpCompress.Test/ArchiveTests.cs | 32 +++++++++++ .../GZip/GZipArchiveTests.cs | 18 +++++- .../SharpCompress.Test/Rar/RarArchiveTests.cs | 55 +++++++++++++++++++ 28 files changed, 231 insertions(+), 70 deletions(-) diff --git a/src/SharpCompress/Archives/GZip/GZipArchive.cs b/src/SharpCompress/Archives/GZip/GZipArchive.cs index e24f6b78..845e05fb 100644 --- a/src/SharpCompress/Archives/GZip/GZipArchive.cs +++ b/src/SharpCompress/Archives/GZip/GZipArchive.cs @@ -89,7 +89,8 @@ namespace SharpCompress.Archives.GZip protected override IEnumerable LoadVolumes(SourceStream srcStream) { srcStream.LoadAllParts(); - return srcStream.Streams.Select(a => new GZipVolume(a, ReaderOptions)); + int idx = 0; + return srcStream.Streams.Select(a => new GZipVolume(a, ReaderOptions, idx++)); } public static bool IsGZipFile(string filePath) { diff --git a/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs b/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs index a3f57300..1afba647 100644 --- a/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs +++ b/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using SharpCompress.Common.Rar; @@ -13,8 +13,8 @@ namespace SharpCompress.Archives.Rar /// internal class FileInfoRarArchiveVolume : RarVolume { - internal FileInfoRarArchiveVolume(FileInfo fileInfo, ReaderOptions options) - : base(StreamingMode.Seekable, fileInfo.OpenRead(), FixOptions(options)) + internal FileInfoRarArchiveVolume(FileInfo fileInfo, ReaderOptions options, int index = 0) + : base(StreamingMode.Seekable, fileInfo.OpenRead(), FixOptions(options), index) { FileInfo = fileInfo; FileParts = GetVolumeFileParts().ToArray().ToReadOnly(); diff --git a/src/SharpCompress/Archives/Rar/FileInfoRarFilePart.cs b/src/SharpCompress/Archives/Rar/FileInfoRarFilePart.cs index 7b0943d5..b2134e6d 100644 --- a/src/SharpCompress/Archives/Rar/FileInfoRarFilePart.cs +++ b/src/SharpCompress/Archives/Rar/FileInfoRarFilePart.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using SharpCompress.Common.Rar.Headers; namespace SharpCompress.Archives.Rar @@ -6,7 +6,7 @@ namespace SharpCompress.Archives.Rar internal sealed class FileInfoRarFilePart : SeekableFilePart { internal FileInfoRarFilePart(FileInfoRarArchiveVolume volume, string? password, MarkHeader mh, FileHeader fh, FileInfo fi) - : base(mh, fh, volume.Stream, password) + : base(mh, fh, volume.Index, volume.Stream, password) { FileInfo = fi; } diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs index a5d3cc4d..38d0c46c 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.cs @@ -37,16 +37,17 @@ namespace SharpCompress.Archives.Rar { base.SrcStream.LoadAllParts(); //request all streams Stream[] streams = base.SrcStream.Streams.ToArray(); + int idx = 0; if (streams.Length > 1 && IsRarFile(streams[1], ReaderOptions)) //test part 2 - true = multipart not split { base.SrcStream.IsVolumes = true; streams[1].Position = 0; base.SrcStream.Position = 0; - return srcStream.Streams.Select(a => new StreamRarArchiveVolume(a, ReaderOptions)); + return srcStream.Streams.Select(a => new StreamRarArchiveVolume(idx++, a, ReaderOptions)); } else //split mode or single file - return new StreamRarArchiveVolume(base.SrcStream, ReaderOptions).AsEnumerable(); + return new StreamRarArchiveVolume(idx++, base.SrcStream, ReaderOptions).AsEnumerable(); } protected override IReader CreateReaderForSolidExtraction() @@ -58,6 +59,9 @@ namespace SharpCompress.Archives.Rar public override bool IsSolid => Volumes.First().IsSolidArchive; + public virtual int MinVersion => Volumes.First().MinVersion; + public virtual int MaxVersion => Volumes.First().MaxVersion; + #region Creation /// /// Constructor with a FileInfo object to an existing file. diff --git a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs index 38c5ad4e..fb2ba0f8 100644 --- a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs +++ b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs @@ -86,4 +86,4 @@ namespace SharpCompress.Archives.Rar } } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Archives/Rar/SeekableFilePart.cs b/src/SharpCompress/Archives/Rar/SeekableFilePart.cs index d8822a92..1e4758ad 100644 --- a/src/SharpCompress/Archives/Rar/SeekableFilePart.cs +++ b/src/SharpCompress/Archives/Rar/SeekableFilePart.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using SharpCompress.Common.Rar; using SharpCompress.Common.Rar.Headers; @@ -9,8 +9,8 @@ namespace SharpCompress.Archives.Rar private readonly Stream stream; private readonly string? password; - internal SeekableFilePart(MarkHeader mh, FileHeader fh, Stream stream, string? password) - : base(mh, fh) + internal SeekableFilePart(MarkHeader mh, FileHeader fh, int index, Stream stream, string? password) + : base(mh, fh, index) { this.stream = stream; this.password = password; @@ -28,4 +28,4 @@ namespace SharpCompress.Archives.Rar internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName; } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs b/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs index 92602ae9..22f6690e 100644 --- a/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs +++ b/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using SharpCompress.Common.Rar; using SharpCompress.Common.Rar.Headers; @@ -9,8 +9,8 @@ namespace SharpCompress.Archives.Rar { internal class StreamRarArchiveVolume : RarVolume { - internal StreamRarArchiveVolume(Stream stream, ReaderOptions options) - : base(StreamingMode.Seekable, stream, options) + internal StreamRarArchiveVolume(int index, Stream stream, ReaderOptions options) + : base(StreamingMode.Seekable, stream, options, index) { } @@ -21,7 +21,7 @@ namespace SharpCompress.Archives.Rar internal override RarFilePart CreateFilePart(MarkHeader markHeader, FileHeader fileHeader) { - return new SeekableFilePart(markHeader, fileHeader, Stream, ReaderOptions.Password); + return new SeekableFilePart(markHeader, fileHeader, this.Index, Stream, ReaderOptions.Password); } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs index eeae90b2..276f1399 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs @@ -85,7 +85,8 @@ namespace SharpCompress.Archives.SevenZip protected override IEnumerable LoadVolumes(SourceStream srcStream) { base.SrcStream.LoadAllParts(); //request all streams - return new SevenZipVolume(srcStream, ReaderOptions).AsEnumerable(); //simple single volume or split, multivolume not supported + int idx = 0; + return new SevenZipVolume(srcStream, ReaderOptions, idx++).AsEnumerable(); //simple single volume or split, multivolume not supported } public static bool IsSevenZipFile(string filePath) diff --git a/src/SharpCompress/Archives/Tar/TarArchive.cs b/src/SharpCompress/Archives/Tar/TarArchive.cs index 236fccba..51bdbc1f 100644 --- a/src/SharpCompress/Archives/Tar/TarArchive.cs +++ b/src/SharpCompress/Archives/Tar/TarArchive.cs @@ -107,7 +107,8 @@ namespace SharpCompress.Archives.Tar protected override IEnumerable LoadVolumes(SourceStream srcStream) { base.SrcStream.LoadAllParts(); //request all streams - return new TarVolume(srcStream, ReaderOptions).AsEnumerable(); //simple single volume or split, multivolume not supported + int idx = 0; + return new TarVolume(srcStream, ReaderOptions, idx++).AsEnumerable(); //simple single volume or split, multivolume not supported } /// diff --git a/src/SharpCompress/Archives/Zip/ZipArchive.cs b/src/SharpCompress/Archives/Zip/ZipArchive.cs index 168d5838..97f83e02 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchive.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchive.cs @@ -168,6 +168,7 @@ namespace SharpCompress.Archives.Zip base.SrcStream.Position = 0; List streams = base.SrcStream.Streams.ToList(); + int idx = 0; if (streams.Count > 1) //test part 2 - true = multipart not split { streams[1].Position += 4; //skip the POST_DATA_DESCRIPTOR to prevent an exception @@ -182,12 +183,12 @@ namespace SharpCompress.Archives.Zip streams.Add(tmp); //streams[0].Position = 4; //skip the POST_DATA_DESCRIPTOR to prevent an exception - return streams.Select(a => new ZipVolume(a, ReaderOptions)); + return streams.Select(a => new ZipVolume(a, ReaderOptions, idx++)); } } //split mode or single file - return new ZipVolume(base.SrcStream, ReaderOptions).AsEnumerable(); + return new ZipVolume(base.SrcStream, ReaderOptions, idx++).AsEnumerable(); } internal ZipArchive() diff --git a/src/SharpCompress/Common/Entry.cs b/src/SharpCompress/Common/Entry.cs index 26a959bd..06afcabd 100644 --- a/src/SharpCompress/Common/Entry.cs +++ b/src/SharpCompress/Common/Entry.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Linq; namespace SharpCompress.Common { @@ -70,6 +71,8 @@ namespace SharpCompress.Common /// public abstract bool IsSplitAfter { get; } + public int VolumeIndexFirst => this.Parts?.FirstOrDefault()?.Index ?? 0; + public int VolumeIndexLast => this.Parts?.LastOrDefault()?.Index ?? 0; /// public override string ToString() => Key; diff --git a/src/SharpCompress/Common/FilePart.cs b/src/SharpCompress/Common/FilePart.cs index 263838b5..fad184aa 100644 --- a/src/SharpCompress/Common/FilePart.cs +++ b/src/SharpCompress/Common/FilePart.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace SharpCompress.Common { @@ -12,6 +12,7 @@ namespace SharpCompress.Common internal ArchiveEncoding ArchiveEncoding { get; } internal abstract string FilePartName { get; } + public int Index { get; set; } internal abstract Stream GetCompressedStream(); internal abstract Stream? GetRawStream(); diff --git a/src/SharpCompress/Common/GZip/GZipFilePart.cs b/src/SharpCompress/Common/GZip/GZipFilePart.cs index 6edacfe9..c6fd9849 100644 --- a/src/SharpCompress/Common/GZip/GZipFilePart.cs +++ b/src/SharpCompress/Common/GZip/GZipFilePart.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.Collections.Generic; using System.IO; @@ -31,8 +31,8 @@ namespace SharpCompress.Common.GZip internal long EntryStartPosition { get; } internal DateTime? DateModified { get; private set; } - internal int? Crc { get; private set; } - internal int? UncompressedSize { get; private set; } + internal uint? Crc { get; private set; } + internal uint? UncompressedSize { get; private set; } internal override string FilePartName => _name!; @@ -52,8 +52,8 @@ namespace SharpCompress.Common.GZip Span trailer = stackalloc byte[8]; int n = _stream.Read(trailer); - Crc = BinaryPrimitives.ReadInt32LittleEndian(trailer); - UncompressedSize = BinaryPrimitives.ReadInt32LittleEndian(trailer.Slice(4)); + Crc = BinaryPrimitives.ReadUInt32LittleEndian(trailer); + UncompressedSize = BinaryPrimitives.ReadUInt32LittleEndian(trailer.Slice(4)); } private void ReadAndValidateGzipHeader() diff --git a/src/SharpCompress/Common/GZip/GZipVolume.cs b/src/SharpCompress/Common/GZip/GZipVolume.cs index 51c5e246..6d77029f 100644 --- a/src/SharpCompress/Common/GZip/GZipVolume.cs +++ b/src/SharpCompress/Common/GZip/GZipVolume.cs @@ -1,12 +1,12 @@ -using System.IO; +using System.IO; using SharpCompress.Readers; namespace SharpCompress.Common.GZip { public class GZipVolume : Volume { - public GZipVolume(Stream stream, ReaderOptions options) - : base(stream, options) + public GZipVolume(Stream stream, ReaderOptions options, int index = 0) + : base(stream, options, index) { } @@ -20,4 +20,4 @@ namespace SharpCompress.Common.GZip public override bool IsMultiVolume => true; } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/IEntry.cs b/src/SharpCompress/Common/IEntry.cs index 8328ff29..63e8f9ca 100644 --- a/src/SharpCompress/Common/IEntry.cs +++ b/src/SharpCompress/Common/IEntry.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Generic; namespace SharpCompress.Common { @@ -15,9 +16,11 @@ namespace SharpCompress.Common bool IsEncrypted { get; } bool IsSplitAfter { get; } bool IsSolid { get; } + int VolumeIndexFirst { get; } + int VolumeIndexLast { get; } DateTime? LastAccessedTime { get; } DateTime? LastModifiedTime { get; } long Size { get; } int? Attrib { get; } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/IVolume.cs b/src/SharpCompress/Common/IVolume.cs index f19971fe..b29d6be9 100644 --- a/src/SharpCompress/Common/IVolume.cs +++ b/src/SharpCompress/Common/IVolume.cs @@ -1,8 +1,11 @@ -using System; +using System; namespace SharpCompress.Common { public interface IVolume : IDisposable { + int Index { get; } + + string FileName { get; } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Rar/RarFilePart.cs b/src/SharpCompress/Common/Rar/RarFilePart.cs index 6e16dff7..4075198e 100644 --- a/src/SharpCompress/Common/Rar/RarFilePart.cs +++ b/src/SharpCompress/Common/Rar/RarFilePart.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using SharpCompress.Common.Rar.Headers; namespace SharpCompress.Common.Rar @@ -8,11 +8,12 @@ namespace SharpCompress.Common.Rar /// internal abstract class RarFilePart : FilePart { - internal RarFilePart(MarkHeader mh, FileHeader fh) + internal RarFilePart(MarkHeader mh, FileHeader fh, int index) : base(fh.ArchiveEncoding) { MarkHeader = mh; FileHeader = fh; + Index = index; } internal MarkHeader MarkHeader { get; } @@ -24,4 +25,4 @@ namespace SharpCompress.Common.Rar return null; } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Rar/RarVolume.cs b/src/SharpCompress/Common/Rar/RarVolume.cs index 6a4628ac..0546e1f1 100644 --- a/src/SharpCompress/Common/Rar/RarVolume.cs +++ b/src/SharpCompress/Common/Rar/RarVolume.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -14,9 +14,10 @@ namespace SharpCompress.Common.Rar public abstract class RarVolume : Volume { private readonly RarHeaderFactory _headerFactory; + internal int _maxCompressionAlgorithm; - internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options) - : base(stream, options) + internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options, int index = 0) + : base(stream, options, index) { _headerFactory = new RarHeaderFactory(mode, options); } @@ -51,6 +52,8 @@ namespace SharpCompress.Common.Rar case HeaderType.File: { var fh = (FileHeader)header; + if (_maxCompressionAlgorithm < fh.CompressionAlgorithm) + _maxCompressionAlgorithm = fh.CompressionAlgorithm; yield return CreateFilePart(lastMarkHeader!, fh); } break; @@ -110,5 +113,37 @@ namespace SharpCompress.Common.Rar return ArchiveHeader.IsSolid; } } + + public int MinVersion + { + get + { + EnsureArchiveHeaderLoaded(); + if (_maxCompressionAlgorithm >= 50) + return 5; //5-6 + else if (_maxCompressionAlgorithm >= 29) + return 3; //3-4 + else if (_maxCompressionAlgorithm >= 20) + return 2; //2 + else + return 1; + } + } + + public int MaxVersion + { + get + { + EnsureArchiveHeaderLoaded(); + if (_maxCompressionAlgorithm >= 50) + return 6; //5-6 + else if (_maxCompressionAlgorithm >= 29) + return 4; //3-4 + else if (_maxCompressionAlgorithm >= 20) + return 2; //2 + else + return 1; + } + } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs index 5a80508b..4a5a8d43 100644 --- a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs +++ b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using SharpCompress.IO; @@ -26,7 +26,6 @@ namespace SharpCompress.Common.SevenZip internal CFileItem Header { get; } internal CFolder? Folder { get; } - internal int Index { get; } internal override string FilePartName => Header.Name; @@ -105,4 +104,4 @@ namespace SharpCompress.Common.SevenZip internal bool IsEncrypted => Folder!._coders.FindIndex(c => c._methodId._id == CMethodId.K_AES_ID) != -1; } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/SevenZip/SevenZipVolume.cs b/src/SharpCompress/Common/SevenZip/SevenZipVolume.cs index 1609c817..79d6c9d0 100644 --- a/src/SharpCompress/Common/SevenZip/SevenZipVolume.cs +++ b/src/SharpCompress/Common/SevenZip/SevenZipVolume.cs @@ -1,13 +1,13 @@ -using System.IO; +using System.IO; using SharpCompress.Readers; namespace SharpCompress.Common.SevenZip { public class SevenZipVolume : Volume { - public SevenZipVolume(Stream stream, ReaderOptions readerFactoryOptions) - : base(stream, readerFactoryOptions) + public SevenZipVolume(Stream stream, ReaderOptions readerFactoryOptions, int index = 0) + : base(stream, readerFactoryOptions, index) { } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Tar/TarVolume.cs b/src/SharpCompress/Common/Tar/TarVolume.cs index 1ddae4d7..5b76c56f 100644 --- a/src/SharpCompress/Common/Tar/TarVolume.cs +++ b/src/SharpCompress/Common/Tar/TarVolume.cs @@ -1,13 +1,13 @@ -using System.IO; +using System.IO; using SharpCompress.Readers; namespace SharpCompress.Common.Tar { public class TarVolume : Volume { - public TarVolume(Stream stream, ReaderOptions readerOptions) - : base(stream, readerOptions) + public TarVolume(Stream stream, ReaderOptions readerOptions, int index = 0) + : base(stream, readerOptions, index) { } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Volume.cs b/src/SharpCompress/Common/Volume.cs index f1b93d02..8e1446b9 100644 --- a/src/SharpCompress/Common/Volume.cs +++ b/src/SharpCompress/Common/Volume.cs @@ -9,8 +9,9 @@ namespace SharpCompress.Common { private readonly Stream _actualStream; - internal Volume(Stream stream, ReaderOptions readerOptions) + internal Volume(Stream stream, ReaderOptions readerOptions, int index = 0) { + Index = index; ReaderOptions = readerOptions; if (readerOptions.LeaveStreamOpen) { @@ -29,6 +30,10 @@ namespace SharpCompress.Common /// public virtual bool IsFirstVolume => true; + public virtual int Index { get; internal set; } + + public string FileName { get { return (_actualStream as FileStream)?.Name!; } } + /// /// RarArchive is part of a multi-part archive. /// diff --git a/src/SharpCompress/Common/Zip/ZipVolume.cs b/src/SharpCompress/Common/Zip/ZipVolume.cs index aa485fa7..856a5836 100644 --- a/src/SharpCompress/Common/Zip/ZipVolume.cs +++ b/src/SharpCompress/Common/Zip/ZipVolume.cs @@ -1,15 +1,15 @@ -using System.IO; +using System.IO; using SharpCompress.Readers; namespace SharpCompress.Common.Zip { public class ZipVolume : Volume { - public ZipVolume(Stream stream, ReaderOptions readerOptions) - : base(stream, readerOptions) + public ZipVolume(Stream stream, ReaderOptions readerOptions, int index = 0) + : base(stream, readerOptions, index) { } public string? Comment { get; internal set; } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs b/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs index c5f62a44..76c9f201 100644 --- a/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs +++ b/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using SharpCompress.Common.Rar; using SharpCompress.Common.Rar.Headers; @@ -6,8 +6,8 @@ namespace SharpCompress.Readers.Rar { internal class NonSeekableStreamFilePart : RarFilePart { - internal NonSeekableStreamFilePart(MarkHeader mh, FileHeader fh) - : base(mh, fh) + internal NonSeekableStreamFilePart(MarkHeader mh, FileHeader fh, int index = 0) + : base(mh, fh, index) { } @@ -18,4 +18,4 @@ namespace SharpCompress.Readers.Rar internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName; } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Readers/Rar/RarReaderVolume.cs b/src/SharpCompress/Readers/Rar/RarReaderVolume.cs index 98a8c5c0..fa3bbdf1 100644 --- a/src/SharpCompress/Readers/Rar/RarReaderVolume.cs +++ b/src/SharpCompress/Readers/Rar/RarReaderVolume.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using SharpCompress.Common.Rar; using SharpCompress.Common.Rar.Headers; @@ -8,14 +8,14 @@ namespace SharpCompress.Readers.Rar { public class RarReaderVolume : RarVolume { - internal RarReaderVolume(Stream stream, ReaderOptions options) - : base(StreamingMode.Streaming, stream, options) + internal RarReaderVolume(Stream stream, ReaderOptions options, int index = 0) + : base(StreamingMode.Streaming, stream, options, index) { } internal override RarFilePart CreateFilePart(MarkHeader markHeader, FileHeader fileHeader) { - return new NonSeekableStreamFilePart(markHeader, fileHeader); + return new NonSeekableStreamFilePart(markHeader, fileHeader, this.Index); } internal override IEnumerable ReadFileParts() @@ -23,4 +23,4 @@ namespace SharpCompress.Readers.Rar return GetVolumeFileParts(); } } -} \ No newline at end of file +} diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index bfd88569..5c103b78 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -173,6 +173,38 @@ namespace SharpCompress.Test VerifyFiles(); } + protected void ArchiveOpenEntryVolumeIndexTest(int[][] results, ReaderOptions readerOptions = null, params string[] testArchives) + { + ArchiveOpenEntryVolumeIndexTest(results, readerOptions, testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x))); + } + + + protected void ArchiveOpenEntryVolumeIndexTest(int[][] results, ReaderOptions readerOptions, IEnumerable testArchives) + { + string[] src = testArchives.ToArray(); + using (var archive = ArchiveFactory.Open(testArchives.Select(f => new FileInfo(f)), null)) + { + try + { + int idx = 0; + foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) + { + Assert.Equal(entry.VolumeIndexFirst, results[idx][0]); + Assert.Equal(entry.VolumeIndexLast, results[idx][1]); + Assert.Equal(src[entry.VolumeIndexFirst], archive.Volumes.First(a => a.Index == entry.VolumeIndexFirst).FileName); + Assert.Equal(src[entry.VolumeIndexLast], archive.Volumes.First(a => a.Index == entry.VolumeIndexLast).FileName); + + idx++; + } + } + catch (IndexOutOfRangeException) + { + throw; + } + } + } + + protected void ArchiveFileRead(string testArchive, ReaderOptions readerOptions = null) { diff --git a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs index 5f4a7c22..15389a4f 100644 --- a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs +++ b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using SharpCompress.Archives; @@ -107,5 +107,21 @@ namespace SharpCompress.Test.GZip Assert.Equal(size, tarStream.Length); } } + + [Fact] + public void TestGzCrcWithMostSignificaltBitNotNegative() + { + using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"))) + { + using (var archive = GZipArchive.Open(stream)) + { + //process all entries in solid archive until the one we want to test + foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) + { + Assert.InRange(entry.Crc, 0L, 0xFFFFFFFFL); + } + } + } + } } } diff --git a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs index d9d2443a..3580aba3 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs @@ -435,6 +435,42 @@ namespace SharpCompress.Test.Rar ArchiveFileRead("Rar2.rar"); } + [Fact] + public void Rar2_ArchiveVersionTest() + { + string testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Rar2.rar"); + + using (var archive = RarArchive.Open(testArchive)) + { + Assert.Equal(2, archive.MinVersion); + Assert.Equal(2, archive.MaxVersion); + } + } + + [Fact] + public void Rar4_ArchiveVersionTest() + { + string testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Rar4.multi.part01.rar"); + + using (var archive = RarArchive.Open(testArchive)) + { + Assert.Equal(3, archive.MinVersion); + Assert.Equal(4, archive.MaxVersion); + } + } + + [Fact] + public void Rar5_ArchiveVersionTest() + { + string testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Rar5.solid.rar"); + + using (var archive = RarArchive.Open(testArchive)) + { + Assert.Equal(5, archive.MinVersion); + Assert.Equal(6, archive.MaxVersion); + } + } + [Fact] public void Rar4_Multi_ArchiveFileRead() { @@ -575,6 +611,25 @@ namespace SharpCompress.Test.Rar "Rar4.multi.part07.rar"); } + [Fact] + public void Rar4_Multi_ArchiveOpenEntryVolumeIndexTest() + { + ArchiveOpenEntryVolumeIndexTest( + new[] { + new[] { 0, 1 }, //exe - Rar4.multi.part01.rar to Rar4.multi.part02.rar + new[] { 1, 5 }, //jpg - Rar4.multi.part02.rar to Rar4.multi.part06.rar + new[] { 5, 6 } //txt - Rar4.multi.part06.rar to Rar4.multi.part07.rar + }, + null, + "Rar4.multi.part01.rar", + "Rar4.multi.part02.rar", + "Rar4.multi.part03.rar", + "Rar4.multi.part04.rar", + "Rar4.multi.part05.rar", + "Rar4.multi.part06.rar", + "Rar4.multi.part07.rar"); + } + [Fact] public void Rar_Multi_ArchiveFileRead() { From 574a093038df4e60003b555e81ca98380d1eb63d Mon Sep 17 00:00:00 2001 From: Nanook Date: Fri, 15 Jul 2022 21:25:39 +0100 Subject: [PATCH 10/21] Minor tweak that got missed in the last tidy. --- src/SharpCompress/Archives/Rar/RarArchive.cs | 4 ++-- src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs index 38d0c46c..6d43a46b 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.cs @@ -44,10 +44,10 @@ namespace SharpCompress.Archives.Rar streams[1].Position = 0; base.SrcStream.Position = 0; - return srcStream.Streams.Select(a => new StreamRarArchiveVolume(idx++, a, ReaderOptions)); + return srcStream.Streams.Select(a => new StreamRarArchiveVolume(a, ReaderOptions, idx++)); } else //split mode or single file - return new StreamRarArchiveVolume(idx++, base.SrcStream, ReaderOptions).AsEnumerable(); + return new StreamRarArchiveVolume(base.SrcStream, ReaderOptions, idx++).AsEnumerable(); } protected override IReader CreateReaderForSolidExtraction() diff --git a/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs b/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs index 22f6690e..68def3f7 100644 --- a/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs +++ b/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs @@ -9,7 +9,7 @@ namespace SharpCompress.Archives.Rar { internal class StreamRarArchiveVolume : RarVolume { - internal StreamRarArchiveVolume(int index, Stream stream, ReaderOptions options) + internal StreamRarArchiveVolume(Stream stream, ReaderOptions options, int index = 0) : base(StreamingMode.Seekable, stream, options, index) { } From 2946a35b0e8099ed8ec39da51a7ba17487950b32 Mon Sep 17 00:00:00 2001 From: OwnageIsMagic Date: Mon, 18 Jul 2022 04:36:31 +0300 Subject: [PATCH 11/21] WriteAll: use delegate instead of Expression --- src/SharpCompress/Writers/IWriterExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/Writers/IWriterExtensions.cs b/src/SharpCompress/Writers/IWriterExtensions.cs index 376728af..5fc1c82d 100644 --- a/src/SharpCompress/Writers/IWriterExtensions.cs +++ b/src/SharpCompress/Writers/IWriterExtensions.cs @@ -37,7 +37,7 @@ namespace SharpCompress.Writers public static void WriteAll(this IWriter writer, string directory, string searchPattern = "*", - Expression>? fileSearchFunc = null, + Func? fileSearchFunc = null, SearchOption option = SearchOption.TopDirectoryOnly) { if (!Directory.Exists(directory)) @@ -49,10 +49,10 @@ namespace SharpCompress.Writers { fileSearchFunc = n => true; } - foreach (var file in Directory.EnumerateFiles(directory, searchPattern, option).Where(fileSearchFunc.Compile())) + foreach (var file in Directory.EnumerateFiles(directory, searchPattern, option).Where(fileSearchFunc)) { writer.Write(file.Substring(directory.Length), file); } } } -} \ No newline at end of file +} From c1d4ac45aba52952cf1573a82c3f769c73c8beb4 Mon Sep 17 00:00:00 2001 From: David Rant Date: Mon, 18 Jul 2022 17:10:36 +0100 Subject: [PATCH 12/21] Include license when packing --- src/SharpCompress/SharpCompress.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index f35bf43f..2ca161b9 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -30,6 +30,9 @@ False + + + From 6a69c6cd021b5c1bd681fcbfafaf8a91048346f1 Mon Sep 17 00:00:00 2001 From: David Rant Date: Mon, 18 Jul 2022 17:11:06 +0100 Subject: [PATCH 13/21] Reference bundled package license file --- src/SharpCompress/SharpCompress.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 2ca161b9..5127c6d4 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -15,7 +15,7 @@ SharpCompress rar;unrar;zip;unzip;bzip2;gzip;tar;7zip;lzip;xz https://github.com/adamhathcock/sharpcompress - https://github.com/adamhathcock/sharpcompress/blob/master/LICENSE.txt + LICENSE.txt false false SharpCompress is a compression library for NET Standard 2.0/2.1/NET 5.0 that can unrar, decompress 7zip, decompress xz, zip/unzip, tar/untar lzip/unlzip, bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented. From f955031e27957a6272500da14b912231a3c36b2a Mon Sep 17 00:00:00 2001 From: David Rant Date: Mon, 18 Jul 2022 17:16:22 +0100 Subject: [PATCH 14/21] Hide license in IDE --- src/SharpCompress/SharpCompress.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 5127c6d4..71c70a89 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -31,7 +31,7 @@ - + From 109a7c12ead989348f5f02cb4e47d9ff1a3ea5fd Mon Sep 17 00:00:00 2001 From: OwnageIsMagic Date: Tue, 19 Jul 2022 04:03:26 +0300 Subject: [PATCH 15/21] WriteAll: update delegate type --- src/SharpCompress/Writers/IWriterExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Writers/IWriterExtensions.cs b/src/SharpCompress/Writers/IWriterExtensions.cs index 5fc1c82d..8d8c77f1 100644 --- a/src/SharpCompress/Writers/IWriterExtensions.cs +++ b/src/SharpCompress/Writers/IWriterExtensions.cs @@ -37,7 +37,7 @@ namespace SharpCompress.Writers public static void WriteAll(this IWriter writer, string directory, string searchPattern = "*", - Func? fileSearchFunc = null, + Predicate? fileSearchFunc = null, SearchOption option = SearchOption.TopDirectoryOnly) { if (!Directory.Exists(directory)) From 5ca4efac317c8c401d3d675d2bb02c8fbfcfaeda Mon Sep 17 00:00:00 2001 From: OwnageIsMagic Date: Tue, 26 Jul 2022 21:36:00 +0300 Subject: [PATCH 16/21] WriteAll: revert 109a7c1 --- src/SharpCompress/Writers/IWriterExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Writers/IWriterExtensions.cs b/src/SharpCompress/Writers/IWriterExtensions.cs index 8d8c77f1..5fc1c82d 100644 --- a/src/SharpCompress/Writers/IWriterExtensions.cs +++ b/src/SharpCompress/Writers/IWriterExtensions.cs @@ -37,7 +37,7 @@ namespace SharpCompress.Writers public static void WriteAll(this IWriter writer, string directory, string searchPattern = "*", - Predicate? fileSearchFunc = null, + Func? fileSearchFunc = null, SearchOption option = SearchOption.TopDirectoryOnly) { if (!Directory.Exists(directory)) From 7c56df1237e98a6478516d338b16b1f06daf303d Mon Sep 17 00:00:00 2001 From: Lars Vahlenberg Date: Thu, 28 Jul 2022 20:36:28 +0200 Subject: [PATCH 17/21] Mitigation of problems --- .../Common/Zip/StreamingZipFilePart.cs | 16 ++++++++++++---- src/SharpCompress/Readers/AbstractReader.cs | 2 +- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 13 +++++++++++-- tests/SharpCompress.Test/Zip/ZipReaderTests.cs | 18 +++++++++++++++++- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs index fbffe179..f287ab73 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs @@ -43,12 +43,20 @@ namespace SharpCompress.Common.Zip { _decompressionStream ??= GetCompressedStream(); - _decompressionStream.Skip(); - - if (_decompressionStream is DeflateStream deflateStream) + if( Header.CompressionMethod != ZipCompressionMethod.None ) { - rewindableStream.Rewind(deflateStream.InputBuffer); + _decompressionStream.Skip(); + + if (_decompressionStream is DeflateStream deflateStream) + { + rewindableStream.Rewind(deflateStream.InputBuffer); + } } + else + { + // We would need to search for the magic word + } + Skipped = true; } var reader = new BinaryReader(rewindableStream); diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index 80e6cf07..619d834e 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -132,7 +132,6 @@ namespace SharpCompress.Readers private void Skip() { var part = Entry.Parts.First(); - part.Skipped = true; if (ArchiveType != ArchiveType.Rar && !Entry.IsSolid @@ -145,6 +144,7 @@ namespace SharpCompress.Readers { var bytesToAdvance = Entry.CompressedSize; rawStream.Skip(bytesToAdvance); + part.Skipped = true; return; } } diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index dfe68c30..67653e77 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -738,13 +738,22 @@ namespace SharpCompress.Test.Zip [Fact] public void Zip_Uncompressed_Skip_All() { - string zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip"); + var keys = new string[] { "Folder/File1.txt", "Folder/File2.rtf", "Folder2/File1.txt", "Folder2/File2.txt", "DEADBEEF" }; + var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip"); using (var stream = File.Open(zipPath, FileMode.Open, FileAccess.Read)) { IArchive archive = ArchiveFactory.Open(stream); IReader reader = archive.ExtractAllEntries(); + int x = 0; while (reader.MoveToNextEntry()) - ; + { + Assert.Equal(keys[x], reader.Entry.Key); + x++; + } + + // if we implement searching for DataDescriptor on none compressed streams + // this would work, see StreamingZipFilePart function FixStreamedFileLocation + // Assert.Equal(4, x); } } } diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index d2b23877..cc4b215d 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using SharpCompress.Common; using SharpCompress.IO; @@ -368,5 +368,21 @@ namespace SharpCompress.Test.Zip } } + [Fact] + public void Zip_ReaderMoveToNextEntry() + { + var keys = new string[] { "version", "sizehint", "data/0/metadata", "data/0/records" }; + + using (var fileStream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "test_477.zip"))) + using (var reader = ZipReader.Open(fileStream)) + { + foreach( var key in keys) + { + reader.MoveToNextEntry(); + + Assert.Equal(reader.Entry.Key, key); + } + } + } } } From ad633a9dd0b87679040d9f9582bd5f141f9613e7 Mon Sep 17 00:00:00 2001 From: Lars Vahlenberg Date: Thu, 28 Jul 2022 21:20:42 +0200 Subject: [PATCH 18/21] missing test file from error report --- tests/TestArchives/Archives/test_477.zip | Bin 0 -> 542 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/TestArchives/Archives/test_477.zip diff --git a/tests/TestArchives/Archives/test_477.zip b/tests/TestArchives/Archives/test_477.zip new file mode 100644 index 0000000000000000000000000000000000000000..272bd594ab48412f85fa8eb7612684ff6d5db13b GIT binary patch literal 542 zcmWIWW@Zs#;Nak3xKa2igaHY#GcYier4|)u=I0r+Fa&tBb8LTqr;>@bljLf`})$3TnI-U0~Tg<}1z`z96$pyA&N6V)WkPJu^g!vg57*Y~T67>!A zb5lzaLCoq}kVO#X>smgAl(>hS1StbyK7{h3)a3l4l;Y@WrLx4F($r!ltLWI;*Z^-v zCJ_dN?~vUO@*UU_a02RAbWI=!!kiBB8eBbt1(HWWy6hPs?!@$#3RIH<0|P@5!qqTO zaxs7;K;bIE@U`n!$evj@82@jC&~tYu2Z8v=7GMShvIPqf7C?gq+5GQqWgZ~&KCgw) cRnHXdLHq!3RyL3;Sr}LtbQl>J?tnN9042V7r2qf` literal 0 HcmV?d00001 From 5706732c55fff25f4f57b8b082c1fb89359ffd6c Mon Sep 17 00:00:00 2001 From: Lars Vahlenberg Date: Thu, 28 Jul 2022 23:03:06 +0200 Subject: [PATCH 19/21] Naive implementation of searching of DataDescriptor, not compatible with big archives (>32bit), but handles test cases. --- .../Common/Zip/StreamingZipFilePart.cs | 18 ++++++++++ src/SharpCompress/Utility.cs | 35 +++++++++++++++++++ .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 4 +-- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs index f287ab73..9b333038 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs @@ -55,6 +55,24 @@ namespace SharpCompress.Common.Zip else { // We would need to search for the magic word + rewindableStream.Position -= 4; + var pos = rewindableStream.Position; + while( Utility.Find(rewindableStream, new byte[] { 0x50,0x4b,0x07,0x08 } ) ) + { + // We should probably check CRC32 for positive matching as well + var size = rewindableStream.Position - pos; + var br = new BinaryReader(rewindableStream); + br.ReadUInt32(); + br.ReadUInt32(); // CRC32 + var compressed_size = br.ReadUInt32(); + var uncompressed_size = br.ReadUInt32(); + if (compressed_size == size && compressed_size == uncompressed_size ) + { + rewindableStream.Position -= 16; + break; + } + rewindableStream.Position -= 12; + } } Skipped = true; diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index ee732e8d..28979d9d 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -165,6 +165,41 @@ namespace SharpCompress } } + public static bool Find(this Stream source, byte[] array) + { + byte[] buffer = GetTransferByteArray(); + try + { + var pos = source.Position; + int count = 0; + var len = source.Read(buffer, 0, buffer.Length); + source.Position = pos + len; + + do + { + for (int i = 0; i < len; i++) + { + if (array[count] == buffer[i]) + { + count++; + if (count == array.Length) + { + source.Position = source.Position - len + i - array.Length +1; + return true; + } + } + } + } + while ((len = source.Read(buffer, 0, buffer.Length)) > 0); + } + finally + { + ArrayPool.Shared.Return(buffer); + } + + return false; + } + public static DateTime DosDateToDateTime(UInt16 iDate, UInt16 iTime) { int year = iDate / 512 + 1980; diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 67653e77..eb85da5e 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -751,9 +751,7 @@ namespace SharpCompress.Test.Zip x++; } - // if we implement searching for DataDescriptor on none compressed streams - // this would work, see StreamingZipFilePart function FixStreamedFileLocation - // Assert.Equal(4, x); + Assert.Equal(4, x); } } } From 70343b17bcb25c440ed306831844bd78111a35e1 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 29 Jul 2022 09:47:35 +0100 Subject: [PATCH 20/21] add more tests for uncompressed streaming zips --- .../SharpCompress.Test/Zip/ZipReaderTests.cs | 31 ++++++++++++++++++ tests/TestArchives/Archives/Issue_685.zip | Bin 0 -> 542 bytes 2 files changed, 31 insertions(+) create mode 100644 tests/TestArchives/Archives/Issue_685.zip diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index cc4b215d..89cc4c13 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -384,5 +384,36 @@ namespace SharpCompress.Test.Zip } } } + [Fact] + public void Issue_685() + { + var count = 0; + using (var fileStream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Issue_685.zip"))) + using (var reader = ZipReader.Open(fileStream)) + { + + while (reader.MoveToNextEntry()) + { + count++; + reader.OpenEntryStream().Dispose(); // Uncomment for workaround + } + Assert.Equal(4, count); + } + } + + + + [Fact] + public void Zip_Uncompressed_Skip_All() + { + var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip"); + using (var stream = File.Open(zipPath, FileMode.Open, FileAccess.Read)) + { + using (var reader = ReaderFactory.Open(stream)) + { + while (reader.MoveToNextEntry()) { } + } + } + } } } diff --git a/tests/TestArchives/Archives/Issue_685.zip b/tests/TestArchives/Archives/Issue_685.zip new file mode 100644 index 0000000000000000000000000000000000000000..272bd594ab48412f85fa8eb7612684ff6d5db13b GIT binary patch literal 542 zcmWIWW@Zs#;Nak3xKa2igaHY#GcYier4|)u=I0r+Fa&tBb8LTqr;>@bljLf`})$3TnI-U0~Tg<}1z`z96$pyA&N6V)WkPJu^g!vg57*Y~T67>!A zb5lzaLCoq}kVO#X>smgAl(>hS1StbyK7{h3)a3l4l;Y@WrLx4F($r!ltLWI;*Z^-v zCJ_dN?~vUO@*UU_a02RAbWI=!!kiBB8eBbt1(HWWy6hPs?!@$#3RIH<0|P@5!qqTO zaxs7;K;bIE@U`n!$evj@82@jC&~tYu2Z8v=7GMShvIPqf7C?gq+5GQqWgZ~&KCgw) cRnHXdLHq!3RyL3;Sr}LtbQl>J?tnN9042V7r2qf` literal 0 HcmV?d00001 From 3009e6dcfd183760fbdb675249b7a65a2894618b Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 29 Jul 2022 10:45:56 +0100 Subject: [PATCH 21/21] Mark for 0.32.2 --- src/SharpCompress/SharpCompress.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 71c70a89..bcf54b2e 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -2,9 +2,9 @@ SharpCompress - Pure C# Decompression/Compression en-US - 0.32.1 - 0.32.1 - 0.32.1 + 0.32.2 + 0.32.2 + 0.32.2 Adam Hathcock net461;netstandard2.0;netstandard2.1;netcoreapp3.1;net6.0 true