diff --git a/src/SharpCompress/Archives/ArchiveFactory.cs b/src/SharpCompress/Archives/ArchiveFactory.cs index 3f479327..02c10699 100644 --- a/src/SharpCompress/Archives/ArchiveFactory.cs +++ b/src/SharpCompress/Archives/ArchiveFactory.cs @@ -239,4 +239,6 @@ public static class ArchiveFactory } } } + + public static IArchiveFactory AutoFactory { get; } = new AutoArchiveFactory(); } diff --git a/src/SharpCompress/Archives/AutoArchiveFactory.cs b/src/SharpCompress/Archives/AutoArchiveFactory.cs new file mode 100644 index 00000000..14038ea1 --- /dev/null +++ b/src/SharpCompress/Archives/AutoArchiveFactory.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using SharpCompress.Common; +using SharpCompress.Readers; + +namespace SharpCompress.Archives; + +class AutoArchiveFactory : IArchiveFactory +{ + public string Name => nameof(AutoArchiveFactory); + + public ArchiveType? KnownArchiveType => null; + + public IEnumerable GetSupportedExtensions() => throw new NotSupportedException(); + + public bool IsArchive(Stream stream, string? password = null) => + throw new NotSupportedException(); + + public FileInfo? GetFilePart(int index, FileInfo part1) => throw new NotSupportedException(); + + public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) => + ArchiveFactory.Open(stream, readerOptions); + + public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) => + ArchiveFactory.Open(fileInfo, readerOptions); +} diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs index ee165982..88a85e96 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs @@ -163,7 +163,7 @@ public class SevenZipArchive : AbstractArchive([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]) + ) + { + break; + } + + if (canScan == 0) + { + throw new InvalidFormatException("Unable to find 7z signature"); + } + + canScan--; + stream.Position = ++_streamOrigin; } _stream = stream; diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 7d94b29d..29903efe 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -73,27 +73,45 @@ public class ArchiveTests : ReaderTests } } - protected void ArchiveStreamRead(string testArchive, ReaderOptions? readerOptions = null) + protected void ArchiveStreamRead(string testArchive, ReaderOptions? readerOptions = null) => + ArchiveStreamRead(ArchiveFactory.AutoFactory, testArchive, readerOptions); + + protected void ArchiveStreamRead( + IArchiveFactory archiveFactory, + string testArchive, + ReaderOptions? readerOptions = null + ) { testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive); - ArchiveStreamRead(readerOptions, testArchive); + ArchiveStreamRead(archiveFactory, readerOptions, testArchive); } protected void ArchiveStreamRead( ReaderOptions? readerOptions = null, params string[] testArchives + ) => ArchiveStreamRead(ArchiveFactory.AutoFactory, readerOptions, testArchives); + + protected void ArchiveStreamRead( + IArchiveFactory archiveFactory, + ReaderOptions? readerOptions = null, + params string[] testArchives ) => ArchiveStreamRead( + archiveFactory, readerOptions, testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x)) ); - protected void ArchiveStreamRead(ReaderOptions? readerOptions, IEnumerable testArchives) + protected void ArchiveStreamRead( + IArchiveFactory archiveFactory, + ReaderOptions? readerOptions, + IEnumerable testArchives + ) { foreach (var path in testArchives) { using (var stream = NonDisposingStream.Create(File.OpenRead(path), true)) - using (var archive = ArchiveFactory.Open(stream, readerOptions)) + using (var archive = archiveFactory.Open(stream, readerOptions)) { try { @@ -218,10 +236,14 @@ public class ArchiveTests : ReaderTests } } - protected void ArchiveFileRead(string testArchive, ReaderOptions? readerOptions = null) + protected void ArchiveFileRead( + IArchiveFactory archiveFactory, + string testArchive, + ReaderOptions? readerOptions = null + ) { testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive); - using (var archive = ArchiveFactory.Open(testArchive, readerOptions)) + using (var archive = archiveFactory.Open(new FileInfo(testArchive), readerOptions)) { foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) { @@ -234,6 +256,9 @@ public class ArchiveTests : ReaderTests VerifyFiles(); } + protected void ArchiveFileRead(string testArchive, ReaderOptions? readerOptions = null) => + ArchiveFileRead(ArchiveFactory.AutoFactory, testArchive, readerOptions); + protected void ArchiveFileSkip( string testArchive, string fileOrder, diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs index 32d978a2..544741ef 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs @@ -4,6 +4,7 @@ using System.Linq; using SharpCompress.Archives; using SharpCompress.Archives.SevenZip; using SharpCompress.Common; +using SharpCompress.Factories; using SharpCompress.Readers; using Xunit; @@ -54,6 +55,14 @@ public class SevenZipArchiveTests : ArchiveTests [Fact] public void SevenZipArchive_LZMA2_PathRead() => ArchiveFileRead("7Zip.LZMA2.7z"); + [Fact] + public void SevenZipArchive_LZMA2_EXE_StreamRead() => + ArchiveStreamRead(new SevenZipFactory(), "7Zip.LZMA2.exe", new() { LookForHeader = true }); + + [Fact] + public void SevenZipArchive_LZMA2_EXE_PathRead() => + ArchiveFileRead(new SevenZipFactory(), "7Zip.LZMA2.exe", new() { LookForHeader = true }); + [Fact] public void SevenZipArchive_LZMA2AES_StreamRead() => ArchiveStreamRead("7Zip.LZMA2.Aes.7z", new ReaderOptions { Password = "testpassword" }); diff --git a/tests/TestArchives/Archives/7Zip.LZMA2.exe b/tests/TestArchives/Archives/7Zip.LZMA2.exe new file mode 100644 index 00000000..889c8318 Binary files /dev/null and b/tests/TestArchives/Archives/7Zip.LZMA2.exe differ