diff --git a/SevenZip.Tests/FileCheckerTests.cs b/SevenZip.Tests/FileCheckerTests.cs index b90f1b3..e195eb1 100644 --- a/SevenZip.Tests/FileCheckerTests.cs +++ b/SevenZip.Tests/FileCheckerTests.cs @@ -27,11 +27,11 @@ public FileCheckerTestData(string testDataFilePath, InArchiveFormat expectedForm /// Path to archive file to test against. /// public string TestDataFilePath { get; } - + public override string ToString() { // Used to get useful test results. - return ExpectedFormat.ToString(); + return Path.GetFileName(TestDataFilePath) + "=" + ExpectedFormat; } } @@ -43,40 +43,110 @@ public class FileCheckerTests /// public static List TestData = new List { - new FileCheckerTestData(@"TestData\arj.arj", InArchiveFormat.Arj), - new FileCheckerTestData(@"TestData\bzip2.bz2", InArchiveFormat.BZip2), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Cab), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Chm), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Compound), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Cpio), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Deb), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Dmg), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Elf), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Flv), - new FileCheckerTestData(@"TestData\gzip.gz", InArchiveFormat.GZip), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Hfs), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Iso), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Lzh), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Lzma), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Lzw), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Msi), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Mslz), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Mub), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Nsis), - new FileCheckerTestData(@"TestData\", InArchiveFormat.PE), - new FileCheckerTestData(@"TestData\rar5.rar", InArchiveFormat.Rar), - new FileCheckerTestData(@"TestData\rar4.rar", InArchiveFormat.Rar4), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Rpm), - new FileCheckerTestData(@"TestData\7z_LZMA2.7z", InArchiveFormat.SevenZip), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Split), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Swf), - new FileCheckerTestData(@"TestData\tar.tar", InArchiveFormat.Tar), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Udf), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Vhd), - new FileCheckerTestData(@"TestData\wim.wim", InArchiveFormat.Wim), - new FileCheckerTestData(@"TestData\xz.xz", InArchiveFormat.XZ), - new FileCheckerTestData(@"TestData\", InArchiveFormat.Xar), - new FileCheckerTestData(@"TestData\zip.zip", InArchiveFormat.Zip) + new FileCheckerTestData(@"TestData\arj.arj", InArchiveFormat.Arj), + new FileCheckerTestData(@"TestData\bzip2.bz2", InArchiveFormat.BZip2), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Cab), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Chm), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Compound), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Cpio), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Deb), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Dmg), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Elf), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Flv), + new FileCheckerTestData(@"TestData\gzip.gz", InArchiveFormat.GZip), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Hfs), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Iso), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Lzh), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Lzma), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Lzw), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Msi), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Mslz), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Mub), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Nsis), + new FileCheckerTestData(@"TestData\", InArchiveFormat.PE), + new FileCheckerTestData(@"TestData\rar5.rar", InArchiveFormat.Rar), + new FileCheckerTestData(@"TestData\rar4.rar", InArchiveFormat.Rar4), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Rpm), + new FileCheckerTestData(@"TestData\7z_LZMA2.7z", InArchiveFormat.SevenZip), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Split), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Swf), + new FileCheckerTestData(@"TestData\tar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Udf), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Vhd), + new FileCheckerTestData(@"TestData\wim.wim", InArchiveFormat.Wim), + new FileCheckerTestData(@"TestData\xz.xz", InArchiveFormat.XZ), + new FileCheckerTestData(@"TestData\", InArchiveFormat.Xar), + new FileCheckerTestData(@"TestData\zip.zip", InArchiveFormat.Zip), + + new FileCheckerTestData(@"TestData\7z\abc.7z", InArchiveFormat.SevenZip), + + new FileCheckerTestData(@"TestData\sfx\abc_7z.exe", InArchiveFormat.SevenZip), + + new FileCheckerTestData(@"TestData\tar\abc.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\abc.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\abc.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZh.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZh.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZh.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZh.txt_pax.tar-with-wrong-extension.zip", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZh.txt_ustar.tar-with-wrong-extension.zip", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZh.txt_v7.tar-with-wrong-extension.zip", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZhello.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZhello.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\BZhello.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\CD001.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\CD001.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\CD001.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\conectix.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\conectix.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\conectix.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FLV.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FLV.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FLV.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FLV.txt_pax.tar-with-wrong-extension.flv", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FLV.txt_ustar.tar-with-wrong-extension.flv", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FLV.txt_v7.tar-with-wrong-extension.flv", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FWS.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FWS.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\FWS.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\H+.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\H+.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\H+.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\ITSF.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\ITSF.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\ITSF.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\ITSFREEFORPERSONALUSE.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\ITSFREEFORPERSONALUSE.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\ITSFREEFORPERSONALUSE.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MSCF.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MSCF.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MSCF.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MSCFish.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MSCFish.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MSCFish.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MZ.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MZ.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MZ.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MZone.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MZone.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\MZone.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\udf.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\udf.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\udf.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\x.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\x.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\x.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xar!.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xar!.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xar!.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xyz.txt_pax.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xyz.txt_ustar.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xyz.txt_v7.tar", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xyz.txt_pax.tar-with-wrong-extension.zip", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xyz.txt_ustar.tar-with-wrong-extension.zip", InArchiveFormat.Tar), + new FileCheckerTestData(@"TestData\tar\xyz.txt_v7.tar-with-wrong-extension.zip", InArchiveFormat.Tar), + + new FileCheckerTestData(@"TestData\zip\abc.zip", InArchiveFormat.Zip) }; [SetUp] @@ -85,20 +155,20 @@ public void SetUp() // Ensures we're in the correct working directory (for test data files). Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); } - + [TestCaseSource(nameof(TestData))] public void CheckFileSignatureTest(FileCheckerTestData data) { if (!File.Exists(data.TestDataFilePath)) { - Assert.Ignore("No test data found for this format."); + var path = Directory.GetCurrentDirectory(); + Assert.Ignore($"No test data found for this format in directory '{path}'."); } else { - int ignored; - bool ignored2; - Assert.AreEqual(data.ExpectedFormat, FileChecker.CheckSignature(data.TestDataFilePath, out ignored, out ignored2)); + Assert.AreEqual(data.ExpectedFormat, + FileChecker.CheckSignature(data.TestDataFilePath, out _, out _)); } } } -} +} \ No newline at end of file diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj index f8ace8a..ebdd3f0 100644 --- a/SevenZip.Tests/SevenZip.Tests.csproj +++ b/SevenZip.Tests/SevenZip.Tests.csproj @@ -33,6 +33,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -60,9 +63,201 @@ PreserveNewest + + PreserveNewest + PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -72,6 +267,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs b/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs index a162287..db95522 100644 --- a/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs +++ b/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs @@ -4,6 +4,7 @@ using System.IO; using System.Threading; using System.Threading.Tasks; + using NUnit.Framework; [TestFixture] @@ -20,13 +21,13 @@ public void AsynchronousCompressDirectoryAndEventsTest() var compressor = new SevenZipCompressor(); - compressor.FilesFound += (o, e) => filesFoundInvoked++; - compressor.FileCompressionStarted += (o, e) => fileCompressionStartedInvoked++; + compressor.FilesFound += (o, e) => filesFoundInvoked++; + compressor.FileCompressionStarted += (o, e) => fileCompressionStartedInvoked++; compressor.FileCompressionFinished += (o, e) => fileCompressionFinishedInvoked++; - compressor.Compressing += (o, e) => compressingInvoked++; - compressor.CompressionFinished += (o, e) => compressionFinishedInvoked++; + compressor.Compressing += (o, e) => compressingInvoked++; + compressor.CompressionFinished += (o, e) => compressionFinishedInvoked++; - compressor.BeginCompressDirectory(@"TestData", TemporaryFile); + compressor.BeginCompressDirectory(@"TestData", TemporaryFile, recursion: false); var timeToWait = 1000; while (compressionFinishedInvoked == 0) @@ -56,7 +57,7 @@ public void AsynchronousCompressFilesTest() { var compressionFinishedInvoked = false; - var compressor = new SevenZipCompressor {DirectoryStructure = false}; + var compressor = new SevenZipCompressor { DirectoryStructure = false }; compressor.CompressionFinished += (o, e) => compressionFinishedInvoked = true; compressor.BeginCompressFiles(TemporaryFile, @"TestData\zip.zip", @"TestData\tar.tar"); @@ -129,7 +130,7 @@ public void AsynchronousModifyArchiveTest() var compressionFinishedInvoked = false; compressor.CompressionFinished += (o, e) => compressionFinishedInvoked = true; - compressor.BeginModifyArchive(TemporaryFile, new Dictionary{{0, @"tartar"}}); + compressor.BeginModifyArchive(TemporaryFile, new Dictionary { { 0, @"tartar" } }); var timeToWait = 1000; while (!compressionFinishedInvoked) @@ -206,7 +207,7 @@ public async Task CompressFilesAsync() public async Task CompressDirectoryAsync() { var compressor = new SevenZipCompressor { DirectoryStructure = false }; - await compressor.CompressDirectoryAsync("TestData", TemporaryFile); + await compressor.CompressDirectoryAsync("TestData", TemporaryFile, recursion: false); Assert.IsTrue(File.Exists(TemporaryFile)); @@ -236,4 +237,4 @@ public async Task CompressFilesEncryptedAsync() } } } -} +} \ No newline at end of file diff --git a/SevenZip.Tests/SevenZipCompressorTests.cs b/SevenZip.Tests/SevenZipCompressorTests.cs index 6f87944..2b55280 100644 --- a/SevenZip.Tests/SevenZipCompressorTests.cs +++ b/SevenZip.Tests/SevenZipCompressorTests.cs @@ -21,7 +21,7 @@ public static List CompressionMethods get { var result = new List(); - foreach(CompressionMethod format in Enum.GetValues(typeof(CompressionMethod))) + foreach (CompressionMethod format in Enum.GetValues(typeof(CompressionMethod))) { result.Add(format); } @@ -84,7 +84,7 @@ public void CompressFileTest() ArchiveFormat = OutArchiveFormat.SevenZip, DirectoryStructure = false }; - + compressor.CompressFiles(TemporaryFile, @"Testdata\7z_LZMA2.7z"); Assert.IsTrue(File.Exists(TemporaryFile)); @@ -105,7 +105,7 @@ public void CompressDirectoryTest() DirectoryStructure = false }; - compressor.CompressDirectory("TestData", TemporaryFile); + compressor.CompressDirectory("TestData", TemporaryFile, recursion: false); Assert.IsTrue(File.Exists(TemporaryFile)); using (var extractor = new SevenZipExtractor(TemporaryFile)) @@ -158,8 +158,8 @@ public void ModifyProtectedArchiveTest() var modificationList = new Dictionary { - {0, "changed.zap"}, - {1, null } + { 0, "changed.zap" }, + { 1, null } }; compressor.ModifyArchive(TemporaryFile, modificationList, "password"); @@ -183,7 +183,7 @@ public void ModifyNonArchiveTest() File.WriteAllText(TemporaryFile, "I'm not an archive."); - var modificationList = new Dictionary {{0, ""}}; + var modificationList = new Dictionary { { 0, "" } }; Assert.Throws(() => compressor.ModifyArchive(TemporaryFile, modificationList)); } @@ -200,7 +200,7 @@ public void CompressWithModifyModeRenameTest() compressor.CompressFiles(TemporaryFile, @"Testdata\7z_LZMA2.7z"); Assert.IsTrue(File.Exists(TemporaryFile)); - compressor.ModifyArchive(TemporaryFile, new Dictionary { { 0, "renamed.7z" }}); + compressor.ModifyArchive(TemporaryFile, new Dictionary { { 0, "renamed.7z" } }); using (var extractor = new SevenZipExtractor(TemporaryFile)) { @@ -254,13 +254,13 @@ public void MultiVolumeCompressionTest() [Test] public void CompressToStreamTest() { - var compressor = new SevenZipCompressor {DirectoryStructure = false}; + var compressor = new SevenZipCompressor { DirectoryStructure = false }; using (var stream = File.Create(TemporaryFile)) { compressor.CompressFiles(stream, @"TestData\zip.zip"); } - + Assert.IsTrue(File.Exists(TemporaryFile)); using (var extractor = new SevenZipExtractor(TemporaryFile)) @@ -284,7 +284,6 @@ public void CompressFromStreamTest() compressor.CompressStream(input, output); } - } Assert.IsTrue(File.Exists(TemporaryFile)); @@ -303,7 +302,7 @@ public void CompressFileDictionaryTest() var fileDict = new Dictionary { - {"zip.zip", @"TestData\zip.zip"} + { "zip.zip", @"TestData\zip.zip" } }; compressor.CompressFileDictionary(fileDict, TemporaryFile); @@ -320,18 +319,18 @@ public void CompressFileDictionaryTest() [Test] public void ThreadedCompressionTest() { - var tempFile1 = Path.Combine(OutputDirectory, "t1.7z"); - var tempFile2 = Path.Combine(OutputDirectory, "t2.7z"); + var tempFile1 = Path.Combine(OutputDirectory, "t1.7z"); + var tempFile2 = Path.Combine(OutputDirectory, "t2.7z"); - var t1 = new Thread(() => + var t1 = new Thread(() => { var tmp = new SevenZipCompressor(); - tmp.CompressDirectory("TestData", tempFile1); - }); + tmp.CompressDirectory("TestData", tempFile1); + }); var t2 = new Thread(() => { - var tmp = new SevenZipCompressor(); + var tmp = new SevenZipCompressor(); tmp.CompressDirectory("TestData", tempFile2); }); @@ -340,9 +339,9 @@ public void ThreadedCompressionTest() t1.Join(); t2.Join(); - Assert.IsTrue(File.Exists(tempFile1)); - Assert.IsTrue(File.Exists(tempFile2)); - } + Assert.IsTrue(File.Exists(tempFile1)); + Assert.IsTrue(File.Exists(tempFile2)); + } [Test, TestCaseSource(nameof(CompressionMethods))] public void CompressDifferentFormatsTest(CompressionMethod method) @@ -358,4 +357,4 @@ public void CompressDifferentFormatsTest(CompressionMethod method) Assert.IsTrue(File.Exists(TemporaryFile)); } } -} +} \ No newline at end of file diff --git a/SevenZip.Tests/TestData/7z/abc.7z b/SevenZip.Tests/TestData/7z/abc.7z new file mode 100644 index 0000000..80e7a72 Binary files /dev/null and b/SevenZip.Tests/TestData/7z/abc.7z differ diff --git a/SevenZip.Tests/TestData/7z/abc.txt b/SevenZip.Tests/TestData/7z/abc.txt new file mode 100644 index 0000000..73b8b4a --- /dev/null +++ b/SevenZip.Tests/TestData/7z/abc.txt @@ -0,0 +1 @@ +Start abc End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/sfx/abc.txt b/SevenZip.Tests/TestData/sfx/abc.txt new file mode 100644 index 0000000..73b8b4a --- /dev/null +++ b/SevenZip.Tests/TestData/sfx/abc.txt @@ -0,0 +1 @@ +Start abc End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/sfx/abc_7z.exe b/SevenZip.Tests/TestData/sfx/abc_7z.exe new file mode 100644 index 0000000..6856227 Binary files /dev/null and b/SevenZip.Tests/TestData/sfx/abc_7z.exe differ diff --git a/SevenZip.Tests/TestData/tar/BZh.txt b/SevenZip.Tests/TestData/tar/BZh.txt new file mode 100644 index 0000000..ad3aaf3 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/BZh.txt @@ -0,0 +1 @@ +Start BZip2 End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/BZh.txt_pax.tar b/SevenZip.Tests/TestData/tar/BZh.txt_pax.tar new file mode 100644 index 0000000..617898d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZh.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/BZh.txt_pax.tar-with-wrong-extension.zip b/SevenZip.Tests/TestData/tar/BZh.txt_pax.tar-with-wrong-extension.zip new file mode 100644 index 0000000..617898d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZh.txt_pax.tar-with-wrong-extension.zip differ diff --git a/SevenZip.Tests/TestData/tar/BZh.txt_ustar.tar b/SevenZip.Tests/TestData/tar/BZh.txt_ustar.tar new file mode 100644 index 0000000..4a90f79 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZh.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/BZh.txt_ustar.tar-with-wrong-extension.zip b/SevenZip.Tests/TestData/tar/BZh.txt_ustar.tar-with-wrong-extension.zip new file mode 100644 index 0000000..4a90f79 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZh.txt_ustar.tar-with-wrong-extension.zip differ diff --git a/SevenZip.Tests/TestData/tar/BZh.txt_v7.tar b/SevenZip.Tests/TestData/tar/BZh.txt_v7.tar new file mode 100644 index 0000000..ef8b387 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZh.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/BZh.txt_v7.tar-with-wrong-extension.zip b/SevenZip.Tests/TestData/tar/BZh.txt_v7.tar-with-wrong-extension.zip new file mode 100644 index 0000000..ef8b387 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZh.txt_v7.tar-with-wrong-extension.zip differ diff --git a/SevenZip.Tests/TestData/tar/BZhello.txt b/SevenZip.Tests/TestData/tar/BZhello.txt new file mode 100644 index 0000000..ad3aaf3 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/BZhello.txt @@ -0,0 +1 @@ +Start BZip2 End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/BZhello.txt_pax.tar b/SevenZip.Tests/TestData/tar/BZhello.txt_pax.tar new file mode 100644 index 0000000..1106c9d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZhello.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/BZhello.txt_ustar.tar b/SevenZip.Tests/TestData/tar/BZhello.txt_ustar.tar new file mode 100644 index 0000000..6d7302f Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZhello.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/BZhello.txt_v7.tar b/SevenZip.Tests/TestData/tar/BZhello.txt_v7.tar new file mode 100644 index 0000000..1da2d30 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/BZhello.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/CD001.txt b/SevenZip.Tests/TestData/tar/CD001.txt new file mode 100644 index 0000000..261873c --- /dev/null +++ b/SevenZip.Tests/TestData/tar/CD001.txt @@ -0,0 +1 @@ +Start ISO End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/CD001.txt_pax.tar b/SevenZip.Tests/TestData/tar/CD001.txt_pax.tar new file mode 100644 index 0000000..b98fdf4 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/CD001.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/CD001.txt_ustar.tar b/SevenZip.Tests/TestData/tar/CD001.txt_ustar.tar new file mode 100644 index 0000000..641f64c Binary files /dev/null and b/SevenZip.Tests/TestData/tar/CD001.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/CD001.txt_v7.tar b/SevenZip.Tests/TestData/tar/CD001.txt_v7.tar new file mode 100644 index 0000000..2cb2185 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/CD001.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/FLV.txt b/SevenZip.Tests/TestData/tar/FLV.txt new file mode 100644 index 0000000..d5f921e --- /dev/null +++ b/SevenZip.Tests/TestData/tar/FLV.txt @@ -0,0 +1 @@ +Start FLV End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/FLV.txt_pax.tar b/SevenZip.Tests/TestData/tar/FLV.txt_pax.tar new file mode 100644 index 0000000..1ac4da0 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FLV.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/FLV.txt_pax.tar-with-wrong-extension.flv b/SevenZip.Tests/TestData/tar/FLV.txt_pax.tar-with-wrong-extension.flv new file mode 100644 index 0000000..1ac4da0 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FLV.txt_pax.tar-with-wrong-extension.flv differ diff --git a/SevenZip.Tests/TestData/tar/FLV.txt_ustar.tar b/SevenZip.Tests/TestData/tar/FLV.txt_ustar.tar new file mode 100644 index 0000000..0b9d2b2 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FLV.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/FLV.txt_ustar.tar-with-wrong-extension.flv b/SevenZip.Tests/TestData/tar/FLV.txt_ustar.tar-with-wrong-extension.flv new file mode 100644 index 0000000..0b9d2b2 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FLV.txt_ustar.tar-with-wrong-extension.flv differ diff --git a/SevenZip.Tests/TestData/tar/FLV.txt_v7.tar b/SevenZip.Tests/TestData/tar/FLV.txt_v7.tar new file mode 100644 index 0000000..d053bef Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FLV.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/FLV.txt_v7.tar-with-wrong-extension.flv b/SevenZip.Tests/TestData/tar/FLV.txt_v7.tar-with-wrong-extension.flv new file mode 100644 index 0000000..d053bef Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FLV.txt_v7.tar-with-wrong-extension.flv differ diff --git a/SevenZip.Tests/TestData/tar/FWS.txt b/SevenZip.Tests/TestData/tar/FWS.txt new file mode 100644 index 0000000..d017858 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/FWS.txt @@ -0,0 +1 @@ +Start Swf End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/FWS.txt_pax.tar b/SevenZip.Tests/TestData/tar/FWS.txt_pax.tar new file mode 100644 index 0000000..93ae75f Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FWS.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/FWS.txt_ustar.tar b/SevenZip.Tests/TestData/tar/FWS.txt_ustar.tar new file mode 100644 index 0000000..d3d95f2 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FWS.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/FWS.txt_v7.tar b/SevenZip.Tests/TestData/tar/FWS.txt_v7.tar new file mode 100644 index 0000000..e234928 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/FWS.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/H+.txt b/SevenZip.Tests/TestData/tar/H+.txt new file mode 100644 index 0000000..e000d1d --- /dev/null +++ b/SevenZip.Tests/TestData/tar/H+.txt @@ -0,0 +1 @@ +Start Hfs End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/H+.txt_pax.tar b/SevenZip.Tests/TestData/tar/H+.txt_pax.tar new file mode 100644 index 0000000..b3921f1 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/H+.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/H+.txt_ustar.tar b/SevenZip.Tests/TestData/tar/H+.txt_ustar.tar new file mode 100644 index 0000000..e5f9b39 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/H+.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/H+.txt_v7.tar b/SevenZip.Tests/TestData/tar/H+.txt_v7.tar new file mode 100644 index 0000000..e2b1308 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/H+.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/ITSF.txt b/SevenZip.Tests/TestData/tar/ITSF.txt new file mode 100644 index 0000000..9a7a802 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/ITSF.txt @@ -0,0 +1 @@ +Start Chm End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/ITSF.txt_pax.tar b/SevenZip.Tests/TestData/tar/ITSF.txt_pax.tar new file mode 100644 index 0000000..4c78e7a Binary files /dev/null and b/SevenZip.Tests/TestData/tar/ITSF.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/ITSF.txt_ustar.tar b/SevenZip.Tests/TestData/tar/ITSF.txt_ustar.tar new file mode 100644 index 0000000..7a43ab0 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/ITSF.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/ITSF.txt_v7.tar b/SevenZip.Tests/TestData/tar/ITSF.txt_v7.tar new file mode 100644 index 0000000..8deb68d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/ITSF.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt new file mode 100644 index 0000000..9a7a802 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt @@ -0,0 +1 @@ +Start Chm End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_pax.tar b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_pax.tar new file mode 100644 index 0000000..08f2aea Binary files /dev/null and b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_ustar.tar b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_ustar.tar new file mode 100644 index 0000000..4dec1bf Binary files /dev/null and b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_v7.tar b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_v7.tar new file mode 100644 index 0000000..7a925a9 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/ITSFREEFORPERSONALUSE.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/MSCF.txt b/SevenZip.Tests/TestData/tar/MSCF.txt new file mode 100644 index 0000000..0dbd50f --- /dev/null +++ b/SevenZip.Tests/TestData/tar/MSCF.txt @@ -0,0 +1 @@ +Start CAB End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/MSCF.txt_pax.tar b/SevenZip.Tests/TestData/tar/MSCF.txt_pax.tar new file mode 100644 index 0000000..0ef68bc Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MSCF.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/MSCF.txt_ustar.tar b/SevenZip.Tests/TestData/tar/MSCF.txt_ustar.tar new file mode 100644 index 0000000..83e8831 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MSCF.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/MSCF.txt_v7.tar b/SevenZip.Tests/TestData/tar/MSCF.txt_v7.tar new file mode 100644 index 0000000..568f1a2 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MSCF.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/MSCFish.txt b/SevenZip.Tests/TestData/tar/MSCFish.txt new file mode 100644 index 0000000..0dbd50f --- /dev/null +++ b/SevenZip.Tests/TestData/tar/MSCFish.txt @@ -0,0 +1 @@ +Start CAB End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/MSCFish.txt_pax.tar b/SevenZip.Tests/TestData/tar/MSCFish.txt_pax.tar new file mode 100644 index 0000000..c5b0ebe Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MSCFish.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/MSCFish.txt_ustar.tar b/SevenZip.Tests/TestData/tar/MSCFish.txt_ustar.tar new file mode 100644 index 0000000..62cb412 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MSCFish.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/MSCFish.txt_v7.tar b/SevenZip.Tests/TestData/tar/MSCFish.txt_v7.tar new file mode 100644 index 0000000..f76e86e Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MSCFish.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/MZ.txt b/SevenZip.Tests/TestData/tar/MZ.txt new file mode 100644 index 0000000..39f4969 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/MZ.txt @@ -0,0 +1 @@ +Start PE End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/MZ.txt_pax.tar b/SevenZip.Tests/TestData/tar/MZ.txt_pax.tar new file mode 100644 index 0000000..a77a2ca Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MZ.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/MZ.txt_ustar.tar b/SevenZip.Tests/TestData/tar/MZ.txt_ustar.tar new file mode 100644 index 0000000..90684ea Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MZ.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/MZ.txt_v7.tar b/SevenZip.Tests/TestData/tar/MZ.txt_v7.tar new file mode 100644 index 0000000..79d4a5e Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MZ.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/MZone.txt b/SevenZip.Tests/TestData/tar/MZone.txt new file mode 100644 index 0000000..39f4969 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/MZone.txt @@ -0,0 +1 @@ +Start PE End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/MZone.txt_pax.tar b/SevenZip.Tests/TestData/tar/MZone.txt_pax.tar new file mode 100644 index 0000000..c744057 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MZone.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/MZone.txt_ustar.tar b/SevenZip.Tests/TestData/tar/MZone.txt_ustar.tar new file mode 100644 index 0000000..608d5cc Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MZone.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/MZone.txt_v7.tar b/SevenZip.Tests/TestData/tar/MZone.txt_v7.tar new file mode 100644 index 0000000..2ebd882 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/MZone.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/abc.txt b/SevenZip.Tests/TestData/tar/abc.txt new file mode 100644 index 0000000..73b8b4a --- /dev/null +++ b/SevenZip.Tests/TestData/tar/abc.txt @@ -0,0 +1 @@ +Start abc End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/abc.txt_pax.tar b/SevenZip.Tests/TestData/tar/abc.txt_pax.tar new file mode 100644 index 0000000..630d257 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/abc.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/abc.txt_ustar.tar b/SevenZip.Tests/TestData/tar/abc.txt_ustar.tar new file mode 100644 index 0000000..cd20c16 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/abc.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/abc.txt_v7.tar b/SevenZip.Tests/TestData/tar/abc.txt_v7.tar new file mode 100644 index 0000000..a261a13 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/abc.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/conectix.txt b/SevenZip.Tests/TestData/tar/conectix.txt new file mode 100644 index 0000000..31f9460 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/conectix.txt @@ -0,0 +1 @@ +Start Vhd End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/conectix.txt_pax.tar b/SevenZip.Tests/TestData/tar/conectix.txt_pax.tar new file mode 100644 index 0000000..34acc4b Binary files /dev/null and b/SevenZip.Tests/TestData/tar/conectix.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/conectix.txt_ustar.tar b/SevenZip.Tests/TestData/tar/conectix.txt_ustar.tar new file mode 100644 index 0000000..7e58bbe Binary files /dev/null and b/SevenZip.Tests/TestData/tar/conectix.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/conectix.txt_v7.tar b/SevenZip.Tests/TestData/tar/conectix.txt_v7.tar new file mode 100644 index 0000000..8ec938d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/conectix.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/udf.txt b/SevenZip.Tests/TestData/tar/udf.txt new file mode 100644 index 0000000..5fa53e6 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/udf.txt @@ -0,0 +1 @@ +Start udf End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/udf.txt_pax.tar b/SevenZip.Tests/TestData/tar/udf.txt_pax.tar new file mode 100644 index 0000000..a1de624 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/udf.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/udf.txt_ustar.tar b/SevenZip.Tests/TestData/tar/udf.txt_ustar.tar new file mode 100644 index 0000000..b1b3d40 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/udf.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/udf.txt_v7.tar b/SevenZip.Tests/TestData/tar/udf.txt_v7.tar new file mode 100644 index 0000000..3897adb Binary files /dev/null and b/SevenZip.Tests/TestData/tar/udf.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/x.txt b/SevenZip.Tests/TestData/tar/x.txt new file mode 100644 index 0000000..5321660 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/x.txt @@ -0,0 +1 @@ +Start DMG End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/x.txt_pax.tar b/SevenZip.Tests/TestData/tar/x.txt_pax.tar new file mode 100644 index 0000000..b227a36 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/x.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/x.txt_ustar.tar b/SevenZip.Tests/TestData/tar/x.txt_ustar.tar new file mode 100644 index 0000000..a22dfaa Binary files /dev/null and b/SevenZip.Tests/TestData/tar/x.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/x.txt_v7.tar b/SevenZip.Tests/TestData/tar/x.txt_v7.tar new file mode 100644 index 0000000..597aaf2 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/x.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/xar!.txt b/SevenZip.Tests/TestData/tar/xar!.txt new file mode 100644 index 0000000..fec67a1 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/xar!.txt @@ -0,0 +1 @@ +Start Xar End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/xar!.txt_pax.tar b/SevenZip.Tests/TestData/tar/xar!.txt_pax.tar new file mode 100644 index 0000000..c0e6596 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xar!.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/xar!.txt_ustar.tar b/SevenZip.Tests/TestData/tar/xar!.txt_ustar.tar new file mode 100644 index 0000000..03ca35d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xar!.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/xar!.txt_v7.tar b/SevenZip.Tests/TestData/tar/xar!.txt_v7.tar new file mode 100644 index 0000000..a744832 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xar!.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/xyz.txt b/SevenZip.Tests/TestData/tar/xyz.txt new file mode 100644 index 0000000..5321660 --- /dev/null +++ b/SevenZip.Tests/TestData/tar/xyz.txt @@ -0,0 +1 @@ +Start DMG End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/tar/xyz.txt_pax.tar b/SevenZip.Tests/TestData/tar/xyz.txt_pax.tar new file mode 100644 index 0000000..85662b6 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xyz.txt_pax.tar differ diff --git a/SevenZip.Tests/TestData/tar/xyz.txt_pax.tar-with-wrong-extension.zip b/SevenZip.Tests/TestData/tar/xyz.txt_pax.tar-with-wrong-extension.zip new file mode 100644 index 0000000..85662b6 Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xyz.txt_pax.tar-with-wrong-extension.zip differ diff --git a/SevenZip.Tests/TestData/tar/xyz.txt_ustar.tar b/SevenZip.Tests/TestData/tar/xyz.txt_ustar.tar new file mode 100644 index 0000000..c55371d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xyz.txt_ustar.tar differ diff --git a/SevenZip.Tests/TestData/tar/xyz.txt_ustar.tar-with-wrong-extension.zip b/SevenZip.Tests/TestData/tar/xyz.txt_ustar.tar-with-wrong-extension.zip new file mode 100644 index 0000000..c55371d Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xyz.txt_ustar.tar-with-wrong-extension.zip differ diff --git a/SevenZip.Tests/TestData/tar/xyz.txt_v7.tar b/SevenZip.Tests/TestData/tar/xyz.txt_v7.tar new file mode 100644 index 0000000..93db49e Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xyz.txt_v7.tar differ diff --git a/SevenZip.Tests/TestData/tar/xyz.txt_v7.tar-with-wrong-extension.zip b/SevenZip.Tests/TestData/tar/xyz.txt_v7.tar-with-wrong-extension.zip new file mode 100644 index 0000000..93db49e Binary files /dev/null and b/SevenZip.Tests/TestData/tar/xyz.txt_v7.tar-with-wrong-extension.zip differ diff --git a/SevenZip.Tests/TestData/zip/abc.txt b/SevenZip.Tests/TestData/zip/abc.txt new file mode 100644 index 0000000..73b8b4a --- /dev/null +++ b/SevenZip.Tests/TestData/zip/abc.txt @@ -0,0 +1 @@ +Start abc End \ No newline at end of file diff --git a/SevenZip.Tests/TestData/zip/abc.zip b/SevenZip.Tests/TestData/zip/abc.zip new file mode 100644 index 0000000..33cbbca Binary files /dev/null and b/SevenZip.Tests/TestData/zip/abc.zip differ diff --git a/SevenZip.sln.DotSettings b/SevenZip.sln.DotSettings index a015642..e402a57 100644 --- a/SevenZip.sln.DotSettings +++ b/SevenZip.sln.DotSettings @@ -1,2 +1,35 @@  + True + True + False + True + 0 + 0 + 0 + 0 + 1 + LEAVE_MULTIPLE + USUAL_INDENT + 4 + True + True + False + True + False + False + True + False + 4 + False + False + ZeroIndent + ZeroIndent + False + 1 + False + False + True + True + True + True True \ No newline at end of file diff --git a/SevenZip/DuplicateKeyComparer.cs b/SevenZip/DuplicateKeyComparer.cs new file mode 100644 index 0000000..77953bd --- /dev/null +++ b/SevenZip/DuplicateKeyComparer.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace SevenZip +{ + // from http://stackoverflow.com/questions/5716423/c-sharp-sortable-collection-which-allows-duplicate-keys/21886340#21886340 + public class DuplicateKeyComparer + : IComparer + where TKey : IComparable + { + #region Fields + + private readonly bool m_descending; + + #endregion + + #region Constructors + + public DuplicateKeyComparer(bool i_descending = false) + { + m_descending = i_descending; + } + + #endregion + + #region Public Methods + + public virtual int Compare(TKey x, TKey y) + { + int result = m_descending + ? y.CompareTo(x) + : x.CompareTo(y); + + if (result == 0) + return 1; // Handle equality as being greater + + return result; + } + + #endregion + } +} \ No newline at end of file diff --git a/SevenZip/FileChecker.cs b/SevenZip/FileChecker.cs index 810b542..475bf8c 100644 --- a/SevenZip/FileChecker.cs +++ b/SevenZip/FileChecker.cs @@ -1,7 +1,10 @@ namespace SevenZip { using System; + using System.Collections.Generic; using System.IO; + using System.Linq; + using System.Text; #if UNMANAGED /// @@ -13,190 +16,131 @@ internal static class FileChecker private const int SIGNATURE_SIZE = 21; private const int SFX_SCAN_LENGTH = 256 * 1024; - private static bool SpecialDetect(Stream stream, int offset, InArchiveFormat expectedFormat) + /// + /// Gets the InArchiveFormat for a specific extension. + /// + /// The stream to identify. + /// The archive beginning offset. + /// True if the original format of the stream is PE; otherwise, false. + /// Corresponding InArchiveFormat. + public static InArchiveFormat CheckSignature(Stream stream, out int offset, out bool isExecutable) { - if (stream.Length > offset + SIGNATURE_SIZE) - { - var signature = new byte[SIGNATURE_SIZE]; - var bytesRequired = SIGNATURE_SIZE; - var index = 0; - stream.Seek(offset, SeekOrigin.Begin); - - while (bytesRequired > 0) - { - var bytesRead = stream.Read(signature, index, bytesRequired); - bytesRequired -= bytesRead; - index += bytesRead; - } - - var actualSignature = BitConverter.ToString(signature); - - foreach (var expectedSignature in Formats.InSignatureFormats.Keys) - { - if (Formats.InSignatureFormats[expectedSignature] != expectedFormat) - { - continue; - } - - if (actualSignature.StartsWith(expectedSignature, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - } - - return false; + return CheckSignature((InArchiveFormat)(-1), stream, out offset, out isExecutable); } /// /// Gets the InArchiveFormat for a specific extension. /// + /// The InArchiveFormat that was detected by the extension of the filename. /// The stream to identify. /// The archive beginning offset. /// True if the original format of the stream is PE; otherwise, false. /// Corresponding InArchiveFormat. - public static InArchiveFormat CheckSignature(Stream stream, out int offset, out bool isExecutable) + private static InArchiveFormat CheckSignature(InArchiveFormat formatByFileName, + Stream stream, + out int offset, + out bool isExecutable) { offset = 0; + isExecutable = false; if (!stream.CanRead) { throw new ArgumentException("The stream must be readable."); } - if (stream.Length < SIGNATURE_SIZE) + if (!stream.CanSeek) { - throw new ArgumentException("The stream is invalid."); + throw new ArgumentException("The stream must be seekable."); } - #region Get file signature + var formatsByData = new SortedList(new DuplicateKeyComparer(true)); - var signature = new byte[SIGNATURE_SIZE]; - var bytesRequired = SIGNATURE_SIZE; - var index = 0; - stream.Seek(0, SeekOrigin.Begin); - - while (bytesRequired > 0) + foreach (var format in new[] { - var bytesRead = stream.Read(signature, index, bytesRequired); - bytesRequired -= bytesRead; - index += bytesRead; - } - - var actualSignature = BitConverter.ToString(signature); - - #endregion - - var suspectedFormat = InArchiveFormat.XZ; // any except PE and Cab - isExecutable = false; - - foreach (var expectedSignature in Formats.InSignatureFormats.Keys) - { - if (actualSignature.StartsWith(expectedSignature, StringComparison.OrdinalIgnoreCase) || - actualSignature.Substring(6).StartsWith(expectedSignature, StringComparison.OrdinalIgnoreCase) && - Formats.InSignatureFormats[expectedSignature] == InArchiveFormat.Lzh) - { - if (Formats.InSignatureFormats[expectedSignature] == InArchiveFormat.PE) - { - suspectedFormat = InArchiveFormat.PE; - isExecutable = true; - } - else - { - return Formats.InSignatureFormats[expectedSignature]; - } - } - } - - // Many Microsoft formats - if (actualSignature.StartsWith("D0-CF-11-E0-A1-B1-1A-E1", StringComparison.OrdinalIgnoreCase)) - { - suspectedFormat = InArchiveFormat.Cab; // != InArchiveFormat.XZ - } - - #region SpecialDetect - - try + InArchiveFormat.Arj, + InArchiveFormat.BZip2, + InArchiveFormat.Cab, + InArchiveFormat.Chm, + InArchiveFormat.Deb, + InArchiveFormat.Dmg, + InArchiveFormat.Elf, + InArchiveFormat.Flv, + InArchiveFormat.GZip, + InArchiveFormat.Hfs, + InArchiveFormat.Iso, + InArchiveFormat.Lzh, + InArchiveFormat.Lzma, + InArchiveFormat.Lzw, + InArchiveFormat.Mub, + InArchiveFormat.PE, + InArchiveFormat.Rar, + InArchiveFormat.Rar4, + InArchiveFormat.Rpm, + InArchiveFormat.SevenZip, + InArchiveFormat.Swf, + InArchiveFormat.Tar, + InArchiveFormat.Udf, + InArchiveFormat.Vhd, + InArchiveFormat.Wim, + InArchiveFormat.XZ, + InArchiveFormat.Xar, + InArchiveFormat.Zip, + }) { - SpecialDetect(stream, 257, InArchiveFormat.Tar); + int resultQuality = CheckSignatureIsFormat(format, stream, 0); + if (resultQuality > 0) + formatsByData.Add(resultQuality, format); } - catch (ArgumentException) {} - if (SpecialDetect(stream, 0x8001, InArchiveFormat.Iso)) - { - return InArchiveFormat.Iso; - } - - if (SpecialDetect(stream, 0x8801, InArchiveFormat.Iso)) - { - return InArchiveFormat.Iso; - } - - if (SpecialDetect(stream, 0x9001, InArchiveFormat.Iso)) - { - return InArchiveFormat.Iso; - } + var detectedFormat = (InArchiveFormat)(-1); - if (SpecialDetect(stream, 0x9001, InArchiveFormat.Iso)) + if (formatsByData.Count == 0) { - return InArchiveFormat.Iso; + detectedFormat = formatByFileName; } - - if (SpecialDetect(stream, 0x400, InArchiveFormat.Hfs)) - { - return InArchiveFormat.Hfs; - } - - #region Last resort for tar - can mistake - - if (stream.Length >= 1024) + else if (formatsByData.Count == 1) { - stream.Seek(-1024, SeekOrigin.End); - var buf = new byte[1024]; - stream.Read(buf, 0, 1024); - var isTar = true; - - for (var i = 0; i < 1024; i++) + // Even if the output is always "detectedFormat = formatByData", still keep all these if-else paths because they explain the criteria of the decisions. + // It may be simplified again if the detection of the formatByData has been made more robust and reliable. + var formatByData = formatsByData.Values[0]; + if (formatByData == formatByFileName // Use found format-by-data if it matches the format-by-filename + || formatByFileName == (InArchiveFormat)(-1)) // or if a match is impossible because no format-by-filename exists. { - isTar = isTar && buf[i] == 0; + detectedFormat = formatByData; } - - if (isTar) + else if (formatByData == InArchiveFormat.Rar4 + && formatByFileName == InArchiveFormat.Rar) { - return InArchiveFormat.Tar; + detectedFormat = formatByData; + } + else // The format-by-data does not match format-by-filename. The file extension may be wrong, therefore the format-by-data is used. + { + detectedFormat = formatByData; } } - - #endregion - - #endregion - - #region Check if it is an SFX archive or a file with an embedded archive. - - if (suspectedFormat != InArchiveFormat.XZ) + else // more than one match { - #region Get first Min(stream.Length, SFX_SCAN_LENGTH) bytes - - var scanLength = Math.Min(stream.Length, SFX_SCAN_LENGTH); - signature = new byte[scanLength]; - bytesRequired = (int)scanLength; - index = 0; - stream.Seek(0, SeekOrigin.Begin); - - while (bytesRequired > 0) + if (formatsByData.ContainsValue(InArchiveFormat.Tar) + && formatByFileName == InArchiveFormat.Tar) { - var bytesRead = stream.Read(signature, index, bytesRequired); - bytesRequired -= bytesRead; - index += bytesRead; + detectedFormat = formatByFileName; } + else + { + detectedFormat = formatsByData.Values[0]; // Use the found format with the highest result quality. + } + } - actualSignature = BitConverter.ToString(signature); - - #endregion + if (detectedFormat == InArchiveFormat.PE) // If the file is an executable, then check if SFX archive or a file with an embedded archive. + { + isExecutable = true; + var data = GetStreamData(stream, 0, SFX_SCAN_LENGTH, true); + var formatsInPE = new SortedList>(new DuplicateKeyComparer(true)); - foreach (var format in new[] + foreach (var format in new[] { - InArchiveFormat.Zip, + InArchiveFormat.Zip, InArchiveFormat.SevenZip, InArchiveFormat.Rar4, InArchiveFormat.Rar, @@ -204,25 +148,29 @@ public static InArchiveFormat CheckSignature(Stream stream, out int offset, out InArchiveFormat.Arj }) { - var pos = actualSignature.IndexOf(Formats.InSignatureFormatsReversed[format]); + var pos = data.IndexOfSequence(Formats.ArchiveFormatSignatures[format]); if (pos > -1) { - offset = pos / 3; - return format; + int resultQuality = CheckSignatureIsFormat(format, stream, pos); + if (resultQuality > 0) + formatsInPE.Add(resultQuality, new Tuple(format, pos)); } } - // Nothing - if (suspectedFormat == InArchiveFormat.PE) + if (formatsInPE.Count > 0) { - return InArchiveFormat.PE; + detectedFormat = formatsInPE.Values[0].Item1; + offset = formatsInPE.Values[0].Item2; } } - #endregion + if (detectedFormat == (InArchiveFormat)(-1)) + { + throw new ArgumentException("The stream is invalid or no corresponding signature was found."); + } - throw new ArgumentException("The stream is invalid or no corresponding signature was found."); + return detectedFormat; } /// @@ -232,23 +180,572 @@ public static InArchiveFormat CheckSignature(Stream stream, out int offset, out /// The archive beginning offset. /// True if the original format of the file is PE; otherwise, false. /// Corresponding InArchiveFormat. - /// + /// public static InArchiveFormat CheckSignature(string fileName, out int offset, out bool isExecutable) { + var exception_FBFN = Formats.FormatByFileName(fileName, out var formatByFileName); + using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { try { - return CheckSignature(fs, out offset, out isExecutable); + return CheckSignature(formatByFileName, + fs, + out offset, + out isExecutable); } - catch (ArgumentException) + catch (ArgumentException exception) { offset = 0; isExecutable = false; - return Formats.FormatByFileName(fileName, true); + if (exception_FBFN != null) + throw exception_FBFN; + + return formatByFileName; } } } + + public static int CheckSignatureIsFormat(InArchiveFormat expectedFormat, + Stream stream, + long checkOffset) + { + switch (expectedFormat) + { + case InArchiveFormat.Arj: + return CheckSignatureIsArj(stream, checkOffset); + case InArchiveFormat.BZip2: + return CheckSignatureIsBZip2(stream, checkOffset); + case InArchiveFormat.Cab: + return CheckSignatureIsCab(stream, checkOffset); + case InArchiveFormat.Chm: + return CheckSignatureIsChm(stream, checkOffset); + case InArchiveFormat.Compound: + return CheckSignatureIsCompound(stream, checkOffset); + case InArchiveFormat.Deb: + return CheckSignatureIsDeb(stream, checkOffset); + case InArchiveFormat.Dmg: + return CheckSignatureIsDmg(stream, checkOffset); + case InArchiveFormat.Elf: + return CheckSignatureIsElf(stream, checkOffset); + case InArchiveFormat.Flv: + return CheckSignatureIsFlv(stream, checkOffset); + case InArchiveFormat.GZip: + return CheckSignatureIsGZip(stream, checkOffset); + case InArchiveFormat.Hfs: + return CheckSignatureIsHfs(stream, checkOffset); + case InArchiveFormat.Iso: + return CheckSignatureIsIso(stream, checkOffset); + case InArchiveFormat.Lzh: + return CheckSignatureIsLzh(stream, checkOffset); + case InArchiveFormat.Lzma: + return CheckSignatureIsLzma(stream, checkOffset); + case InArchiveFormat.Lzw: + return CheckSignatureIsLzw(stream, checkOffset); + case InArchiveFormat.Mub: + return CheckSignatureIsMub(stream, checkOffset); + case InArchiveFormat.PE: + return CheckSignatureIsPE(stream, checkOffset); + case InArchiveFormat.Rar: + return CheckSignatureIsRar(stream, checkOffset); + case InArchiveFormat.Rar4: + return CheckSignatureIsRar4(stream, checkOffset); + case InArchiveFormat.Rpm: + return CheckSignatureIsRpm(stream, checkOffset); + case InArchiveFormat.SevenZip: + return CheckSignatureIsSevenZip(stream, checkOffset); + case InArchiveFormat.Swf: + return CheckSignatureIsSwf(stream, checkOffset); + case InArchiveFormat.Tar: + return CheckSignatureIsTar(stream, checkOffset); + case InArchiveFormat.Udf: + return CheckSignatureIsUdf(stream, checkOffset); + case InArchiveFormat.Vhd: + return CheckSignatureIsVhd(stream, checkOffset); + case InArchiveFormat.Wim: + return CheckSignatureIsWim(stream, checkOffset); + case InArchiveFormat.Xar: + return CheckSignatureIsXar(stream, checkOffset); + case InArchiveFormat.XZ: + return CheckSignatureIsXZ(stream, checkOffset); + case InArchiveFormat.Zip: + return CheckSignatureIsZip(stream, checkOffset); + + default: + throw new NotSupportedException(); + } + } + + private static int CheckSignatureIsArj(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_ArjArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsBZip2(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_BZip2Archive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsCab(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_CabArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsChm(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Chm; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsCompound(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_CompoundFile; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsDeb(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_DEB; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsDmg(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_DMG_AppleDiskImage; + long position = checkOffset; + + long signaturePosition = stream.Length - 512; + byte[] actualSignature = GetStreamData(stream, signaturePosition, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsElf(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Elf; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsFlv(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Flv; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsGZip(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_GZipArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsHfs(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Hfs; + long position = 0x400 + checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsIso(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Iso; + long position1 = 0x8001 + checkOffset; + long position2 = 0x8801 + checkOffset; + long position3 = 0x9001 + checkOffset; + + byte[] actualSignature1 = GetStreamData(stream, position1, expectedSignature.Count); + byte[] actualSignature2 = GetStreamData(stream, position2, expectedSignature.Count); + byte[] actualSignature3 = GetStreamData(stream, position3, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature1) + || expectedSignature.SequenceEqual(actualSignature2) + || expectedSignature.SequenceEqual(actualSignature3)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsLzh(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_LzhArchive; + long position = 2 + checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsLzma(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_LzmaArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsLzw(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_LzwArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsMub(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Mub; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + /// + /// Check whether the stream contains the signature of the PE file format and return the quality of the result of the + /// check. + /// + /// The stream that is checked. + /// A numeric value that indicates the quality of the result of the check. If 0, the check has failed. + /// + /// http://docs.microsoft.com/en-us/windows/win32/debug/pe-format
+ /// http://de.wikipedia.org/wiki/Portable_Executable + ///
+ private static int CheckSignatureIsPE(Stream stream, long checkOffset) + { + if (stream.Length < 0x40 + checkOffset) + return 0; + + int resultQuality = 0; + + var expectedSignature_MZ = Formats.Signature_DosExecutable; + var expectedSignature_PE = Formats.Signature_PE_PortableExecutable; + long position_MZ = checkOffset; + long position_PEPosition = 0x3c + checkOffset; // The position of the PE header is defined in 4 bytes at offset 0x3c from the file header begin. + + byte[] actualSignature_MZ = GetStreamData(stream, position_MZ, expectedSignature_MZ.Count); + if (expectedSignature_MZ.SequenceEqual(actualSignature_MZ)) + { + int peHeaderPosition = BitConverter.ToInt32(GetStreamData(stream, position_PEPosition, 4), 0); + long position_PE = peHeaderPosition + checkOffset; + byte[] actualSignature_PE = GetStreamData(stream, position_PE, expectedSignature_PE.Count); + + if (expectedSignature_PE.SequenceEqual(actualSignature_PE)) + { + resultQuality += expectedSignature_MZ.Count + + expectedSignature_PE.Count; + } + } + + return resultQuality; + } + + private static int CheckSignatureIsRar(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_RarArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsRar4(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Rar4Archive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsRpm(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Rpm; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsSevenZip(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_SevenZipArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsSwf(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Swf; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsTar(Stream stream, long checkOffset) + { + const int headerSize = 512; + const int checksumPosInHeader = 148; + const int checksumSize = 8; + + if (stream.Length < headerSize) + return 0; + + int resultQuality = 0; + var expectedSignature = Formats.Signature_USTarArchive; + long position = checkOffset + 257; + + // Tar formats "ustar" and "pax" contain the text "ustar" at position 257. + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + // Tar format "v7" does not contain any signature. Therefore always check the checksum of the header, which is available in all Tar formats. + position = checkOffset; + stream.Position = position; + int actualChecksum; + var headerWithoutChecksum = new List(); + using (var reader = new BinaryReader(stream, Encoding.Default, true)) + { + headerWithoutChecksum.AddRange(reader.ReadBytes(checksumPosInHeader)); + headerWithoutChecksum.AddRange(Encoding.ASCII.GetBytes(new string(' ', checksumSize))); + var actualChecksumBytes = reader.ReadBytes(checksumSize).SkipWhile(value => value < 0x30).TakeWhile(value => value >= 0x30); // the checksum is an ASCII text of the octal value, preceded and/or terminated with space (0x20) or 0x00. + actualChecksum = actualChecksumBytes.Reverse().Select((value, index) => (value - 0x30) * (int)Math.Pow(8, index)).Sum(); // convert each byte to a number (by "- 0x30"), then multiply with octal base at each index, then sum all values. + headerWithoutChecksum.AddRange(reader.ReadBytes(headerSize - checksumPosInHeader - checksumSize)); + } + + int expectedChecksum = headerWithoutChecksum.Select(value => (int)value).Sum(); + if (actualChecksum == expectedChecksum) + resultQuality += headerSize / 10; // Arbitrary decision: use 10% of header size because only the checksum was checked. + + return resultQuality; + } + + private static int CheckSignatureIsUdf(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Udf; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsVhd(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_Vhd; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsWim(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_WimArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsXar(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_XarArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsXZ(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_XZArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static int CheckSignatureIsZip(Stream stream, long checkOffset) + { + int resultQuality = 0; + var expectedSignature = Formats.Signature_ZipArchive; + long position = checkOffset; + + byte[] actualSignature = GetStreamData(stream, position, expectedSignature.Count); + if (expectedSignature.SequenceEqual(actualSignature)) + resultQuality += expectedSignature.Count; + + return resultQuality; + } + + private static byte[] GetStreamData(Stream stream, + long position, + int length, + bool acceptShorterData = false) + { + if (length < 1) + throw new ArgumentOutOfRangeException(nameof(length), length, "value must be >= 1."); + + if (position < 0 + || position > stream.Length) // Start of read would be before start of stream or after end of stream. + return new byte[0]; + + if (position + length > stream.Length) // End of read would be after end of stream. + { + if (!acceptShorterData) + return new byte[0]; + + length = (int)(stream.Length - position); + } + + var data = new byte[length]; + var bytesRequired = length; + var index = 0; + stream.Position = position; + + while (bytesRequired > 0) + { + var bytesRead = stream.Read(data, index, bytesRequired); + bytesRequired -= bytesRead; + index += bytesRead; + } + + return data; + } } #endif } \ No newline at end of file diff --git a/SevenZip/Formats.cs b/SevenZip/Formats.cs index 74d7d83..d4ea579 100644 --- a/SevenZip/Formats.cs +++ b/SevenZip/Formats.cs @@ -12,8 +12,8 @@ public enum InArchiveFormat { /// /// Open 7-zip archive format. - /// - /// Wikipedia information + ///
+ /// Wikipedia information SevenZip, /// /// Proprietary Arj archive format. @@ -140,7 +140,7 @@ public enum InArchiveFormat /// /// Open Xz archive format. /// - /// Wikipedia information + /// Wikipedia information XZ, /// /// MSLZ archive format. @@ -154,7 +154,7 @@ public enum InArchiveFormat /// /// Shockwave Flash format. /// - /// Wikipedia information + /// Wikipedia information Swf, /// /// Windows PE executable format. @@ -241,7 +241,7 @@ public enum InArchiveFormat /// /// Writable archive format enumeration. - /// + /// public enum OutArchiveFormat { /// @@ -259,7 +259,7 @@ public enum OutArchiveFormat /// /// Wikipedia information GZip, - /// + /// /// Open Bzip2 archive format. /// /// Wikipedia information @@ -272,7 +272,7 @@ public enum OutArchiveFormat /// /// Open Xz archive format. /// - /// Wikipedia information + /// Wikipedia information XZ } @@ -354,6 +354,38 @@ public enum CompressionMethod /// public static class Formats { + /// Partially based on the information at "http://www.garykessler.net/library/file_sigs.html" + public static readonly IReadOnlyCollection Signature_ArjArchive = Array.AsReadOnly(new byte[] { 0x60, 0xEA }); + public static readonly IReadOnlyCollection Signature_BZip2Archive = Array.AsReadOnly(new byte[] { 0x42, 0x5A, 0x68 }); + public static readonly IReadOnlyCollection Signature_CabArchive = Array.AsReadOnly(new byte[] { 0x4D, 0x53, 0x43, 0x46 }); + public static readonly IReadOnlyCollection Signature_Chm = Array.AsReadOnly(new byte[] { 0x49, 0x54, 0x53, 0x46 }); + public static readonly IReadOnlyCollection Signature_CompoundFile = Array.AsReadOnly(new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }); + public static readonly IReadOnlyCollection Signature_DEB = Array.AsReadOnly(new byte[] { 0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A, 0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79 }); + public static readonly IReadOnlyCollection Signature_DMG_AppleDiskImage = Array.AsReadOnly(new byte[] { 0x6b, 0x6f, 0x6c, 0x79 }); // "koly" + public static readonly IReadOnlyCollection Signature_DosExecutable = Array.AsReadOnly(new byte[] { 0x4D, 0x5A }); // DOS-EXE header "MZ" + public static readonly IReadOnlyCollection Signature_Elf = Array.AsReadOnly(new byte[] { 0x7F, 0x45, 0x4C, 0x46 }); + public static readonly IReadOnlyCollection Signature_Flv = Array.AsReadOnly(new byte[] { 0x46, 0x4C, 0x56 }); + public static readonly IReadOnlyCollection Signature_GZipArchive = Array.AsReadOnly(new byte[] { 0x1F, 0x8B, 0x08 }); + public static readonly IReadOnlyCollection Signature_Hfs = Array.AsReadOnly(new byte[] { 0x48, 0x2B }); + public static readonly IReadOnlyCollection Signature_Iso = Array.AsReadOnly(new byte[] { 0x43, 0x44, 0x30, 0x30, 0x31 }); + public static readonly IReadOnlyCollection Signature_LzhArchive = Array.AsReadOnly(new byte[] { 0x2D, 0x6C, 0x68 }); + public static readonly IReadOnlyCollection Signature_LzmaArchive = Array.AsReadOnly(new byte[] { 0x5D, 0x00, 0x00, 0x40, 0x00 }); + public static readonly IReadOnlyCollection Signature_LzwArchive = Array.AsReadOnly(new byte[] { 0x1F, 0x9D, 0x90 }); // based on internet resources, the signature is only 2 bytes: 0x1f, 0x9d. + public static readonly IReadOnlyCollection Signature_Mub = Array.AsReadOnly(new byte[] { 0x6d, 0x75, 0x62 }); + public static readonly IReadOnlyCollection Signature_PE_PortableExecutable = Array.AsReadOnly(new byte[] { 0x50, 0x45, 0x00, 0x0 }); // PE header "PE\0\0" + public static readonly IReadOnlyCollection Signature_RarArchive = Array.AsReadOnly(new byte[] { 0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00 }); + public static readonly IReadOnlyCollection Signature_Rar4Archive = Array.AsReadOnly(new byte[] { 0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00 }); + public static readonly IReadOnlyCollection Signature_Rpm = Array.AsReadOnly(new byte[] { 0xED, 0xAB, 0xEE, 0xDB }); + public static readonly IReadOnlyCollection Signature_SevenZipArchive = Array.AsReadOnly(new byte[] { 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C }); + public static readonly IReadOnlyCollection Signature_Swf = Array.AsReadOnly(new byte[] { 0x46, 0x57, 0x53 }); + public static readonly IReadOnlyCollection Signature_USTarArchive = Array.AsReadOnly(new byte[] { 0x75, 0x73, 0x74, 0x61, 0x72 }); + public static readonly IReadOnlyCollection Signature_Udf = Array.AsReadOnly(new byte[] { 0x75, 0x64, 0x66 }); + public static readonly IReadOnlyCollection Signature_Vhd = Array.AsReadOnly(new byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 }); + public static readonly IReadOnlyCollection Signature_WimArchive = Array.AsReadOnly(new byte[] { 0x4D, 0x53, 0x57, 0x49, 0x4D, 0x00, 0x00, 0x00 }); + public static readonly IReadOnlyCollection Signature_XarArchive = Array.AsReadOnly(new byte[] { 0x78, 0x61, 0x72, 0x21 }); + public static readonly IReadOnlyCollection Signature_XZArchive = Array.AsReadOnly(new byte[] { 0xFD, 0x37, 0x7A, 0x58, 0x5A }); + public static readonly IReadOnlyCollection Signature_ZipArchive = Array.AsReadOnly(new byte[] { 0x50, 0x4B, 0x03, 0x04 }); + /*/// /// Gets the max value of the specified enum type. /// @@ -371,199 +403,172 @@ internal static int GetMaxValue(Type type) /// internal static readonly Dictionary InFormatGuids = new Dictionary - #region InFormatGuids initialization + #region InFormatGuids initialization - { - {InArchiveFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000")}, - {InArchiveFormat.Arj, new Guid("23170f69-40c1-278a-1000-000110040000")}, - {InArchiveFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000")}, - {InArchiveFormat.Cab, new Guid("23170f69-40c1-278a-1000-000110080000")}, - {InArchiveFormat.Chm, new Guid("23170f69-40c1-278a-1000-000110e90000")}, - {InArchiveFormat.Compound, new Guid("23170f69-40c1-278a-1000-000110e50000")}, - {InArchiveFormat.Cpio, new Guid("23170f69-40c1-278a-1000-000110ed0000")}, - {InArchiveFormat.Deb, new Guid("23170f69-40c1-278a-1000-000110ec0000")}, - {InArchiveFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000")}, - {InArchiveFormat.Iso, new Guid("23170f69-40c1-278a-1000-000110e70000")}, - {InArchiveFormat.Lzh, new Guid("23170f69-40c1-278a-1000-000110060000")}, - {InArchiveFormat.Lzma, new Guid("23170f69-40c1-278a-1000-0001100a0000")}, - {InArchiveFormat.Nsis, new Guid("23170f69-40c1-278a-1000-000110090000")}, - {InArchiveFormat.Rar, new Guid("23170f69-40c1-278a-1000-000110CC0000")}, - {InArchiveFormat.Rar4, new Guid("23170f69-40c1-278a-1000-000110030000")}, - {InArchiveFormat.Rpm, new Guid("23170f69-40c1-278a-1000-000110eb0000")}, - {InArchiveFormat.Split, new Guid("23170f69-40c1-278a-1000-000110ea0000")}, - {InArchiveFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000")}, - {InArchiveFormat.Wim, new Guid("23170f69-40c1-278a-1000-000110e60000")}, - {InArchiveFormat.Lzw, new Guid("23170f69-40c1-278a-1000-000110050000")}, - {InArchiveFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000")}, - {InArchiveFormat.Udf, new Guid("23170f69-40c1-278a-1000-000110E00000")}, - {InArchiveFormat.Xar, new Guid("23170f69-40c1-278a-1000-000110E10000")}, - {InArchiveFormat.Mub, new Guid("23170f69-40c1-278a-1000-000110E20000")}, - {InArchiveFormat.Hfs, new Guid("23170f69-40c1-278a-1000-000110E30000")}, - {InArchiveFormat.Dmg, new Guid("23170f69-40c1-278a-1000-000110E40000")}, - {InArchiveFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000")}, - {InArchiveFormat.Mslz, new Guid("23170f69-40c1-278a-1000-000110D50000")}, - {InArchiveFormat.PE, new Guid("23170f69-40c1-278a-1000-000110DD0000")}, - {InArchiveFormat.Elf, new Guid("23170f69-40c1-278a-1000-000110DE0000")}, - {InArchiveFormat.Swf, new Guid("23170f69-40c1-278a-1000-000110D70000")}, - {InArchiveFormat.Vhd, new Guid("23170f69-40c1-278a-1000-000110DC0000")}, - {InArchiveFormat.Flv, new Guid("23170f69-40c1-278a-1000-000110D60000")}, - {InArchiveFormat.SquashFS, new Guid("23170f69-40c1-278a-1000-000110D20000")}, - {InArchiveFormat.Lzma86, new Guid("23170f69-40c1-278a-1000-0001100B0000")}, - {InArchiveFormat.Ppmd, new Guid("23170f69-40c1-278a-1000-0001100D0000")}, - {InArchiveFormat.TE, new Guid("23170f69-40c1-278a-1000-000110CF0000")}, - {InArchiveFormat.UEFIc, new Guid("23170f69-40c1-278a-1000-000110D00000")}, - {InArchiveFormat.UEFIs, new Guid("23170f69-40c1-278a-1000-000110D10000")}, - {InArchiveFormat.CramFS, new Guid("23170f69-40c1-278a-1000-000110D30000")}, - {InArchiveFormat.APM, new Guid("23170f69-40c1-278a-1000-000110D40000")}, - {InArchiveFormat.Swfc, new Guid("23170f69-40c1-278a-1000-000110D80000")}, - {InArchiveFormat.Ntfs, new Guid("23170f69-40c1-278a-1000-000110D90000")}, - {InArchiveFormat.Fat, new Guid("23170f69-40c1-278a-1000-000110DA0000")}, - {InArchiveFormat.Mbr, new Guid("23170f69-40c1-278a-1000-000110DB0000")}, - {InArchiveFormat.MachO, new Guid("23170f69-40c1-278a-1000-000110DF0000")} - }; + { + { InArchiveFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000") }, + { InArchiveFormat.Arj, new Guid("23170f69-40c1-278a-1000-000110040000") }, + { InArchiveFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000") }, + { InArchiveFormat.Cab, new Guid("23170f69-40c1-278a-1000-000110080000") }, + { InArchiveFormat.Chm, new Guid("23170f69-40c1-278a-1000-000110e90000") }, + { InArchiveFormat.Compound, new Guid("23170f69-40c1-278a-1000-000110e50000") }, + { InArchiveFormat.Cpio, new Guid("23170f69-40c1-278a-1000-000110ed0000") }, + { InArchiveFormat.Deb, new Guid("23170f69-40c1-278a-1000-000110ec0000") }, + { InArchiveFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000") }, + { InArchiveFormat.Iso, new Guid("23170f69-40c1-278a-1000-000110e70000") }, + { InArchiveFormat.Lzh, new Guid("23170f69-40c1-278a-1000-000110060000") }, + { InArchiveFormat.Lzma, new Guid("23170f69-40c1-278a-1000-0001100a0000") }, + { InArchiveFormat.Nsis, new Guid("23170f69-40c1-278a-1000-000110090000") }, + { InArchiveFormat.Rar, new Guid("23170f69-40c1-278a-1000-000110CC0000") }, + { InArchiveFormat.Rar4, new Guid("23170f69-40c1-278a-1000-000110030000") }, + { InArchiveFormat.Rpm, new Guid("23170f69-40c1-278a-1000-000110eb0000") }, + { InArchiveFormat.Split, new Guid("23170f69-40c1-278a-1000-000110ea0000") }, + { InArchiveFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000") }, + { InArchiveFormat.Wim, new Guid("23170f69-40c1-278a-1000-000110e60000") }, + { InArchiveFormat.Lzw, new Guid("23170f69-40c1-278a-1000-000110050000") }, + { InArchiveFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000") }, + { InArchiveFormat.Udf, new Guid("23170f69-40c1-278a-1000-000110E00000") }, + { InArchiveFormat.Xar, new Guid("23170f69-40c1-278a-1000-000110E10000") }, + { InArchiveFormat.Mub, new Guid("23170f69-40c1-278a-1000-000110E20000") }, + { InArchiveFormat.Hfs, new Guid("23170f69-40c1-278a-1000-000110E30000") }, + { InArchiveFormat.Dmg, new Guid("23170f69-40c1-278a-1000-000110E40000") }, + { InArchiveFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000") }, + { InArchiveFormat.Mslz, new Guid("23170f69-40c1-278a-1000-000110D50000") }, + { InArchiveFormat.PE, new Guid("23170f69-40c1-278a-1000-000110DD0000") }, + { InArchiveFormat.Elf, new Guid("23170f69-40c1-278a-1000-000110DE0000") }, + { InArchiveFormat.Swf, new Guid("23170f69-40c1-278a-1000-000110D70000") }, + { InArchiveFormat.Vhd, new Guid("23170f69-40c1-278a-1000-000110DC0000") }, + { InArchiveFormat.Flv, new Guid("23170f69-40c1-278a-1000-000110D60000") }, + { InArchiveFormat.SquashFS, new Guid("23170f69-40c1-278a-1000-000110D20000") }, + { InArchiveFormat.Lzma86, new Guid("23170f69-40c1-278a-1000-0001100B0000") }, + { InArchiveFormat.Ppmd, new Guid("23170f69-40c1-278a-1000-0001100D0000") }, + { InArchiveFormat.TE, new Guid("23170f69-40c1-278a-1000-000110CF0000") }, + { InArchiveFormat.UEFIc, new Guid("23170f69-40c1-278a-1000-000110D00000") }, + { InArchiveFormat.UEFIs, new Guid("23170f69-40c1-278a-1000-000110D10000") }, + { InArchiveFormat.CramFS, new Guid("23170f69-40c1-278a-1000-000110D30000") }, + { InArchiveFormat.APM, new Guid("23170f69-40c1-278a-1000-000110D40000") }, + { InArchiveFormat.Swfc, new Guid("23170f69-40c1-278a-1000-000110D80000") }, + { InArchiveFormat.Ntfs, new Guid("23170f69-40c1-278a-1000-000110D90000") }, + { InArchiveFormat.Fat, new Guid("23170f69-40c1-278a-1000-000110DA0000") }, + { InArchiveFormat.Mbr, new Guid("23170f69-40c1-278a-1000-000110DB0000") }, + { InArchiveFormat.MachO, new Guid("23170f69-40c1-278a-1000-000110DF0000") } + }; - #endregion + #endregion /// /// List of writable archive format interface guids for 7-zip COM interop. /// internal static readonly Dictionary OutFormatGuids = new Dictionary - #region OutFormatGuids initialization + #region OutFormatGuids initialization - { - {OutArchiveFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000")}, - {OutArchiveFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000")}, - {OutArchiveFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000")}, - {OutArchiveFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000")}, - {OutArchiveFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000")}, - {OutArchiveFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000")}, - }; + { + { OutArchiveFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000") }, + { OutArchiveFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000") }, + { OutArchiveFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000") }, + { OutArchiveFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000") }, + { OutArchiveFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000") }, + { OutArchiveFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000") }, + }; - #endregion + #endregion internal static readonly Dictionary MethodNames = new Dictionary - #region MethodNames initialization + #region MethodNames initialization - { - {CompressionMethod.Copy, "Copy"}, - {CompressionMethod.Deflate, "Deflate"}, - {CompressionMethod.Deflate64, "Deflate64"}, - {CompressionMethod.Lzma, "LZMA"}, - {CompressionMethod.Lzma2, "LZMA2"}, - {CompressionMethod.Ppmd, "PPMd"}, - {CompressionMethod.BZip2, "BZip2"} - }; + { + { CompressionMethod.Copy, "Copy" }, + { CompressionMethod.Deflate, "Deflate" }, + { CompressionMethod.Deflate64, "Deflate64" }, + { CompressionMethod.Lzma, "LZMA" }, + { CompressionMethod.Lzma2, "LZMA2" }, + { CompressionMethod.Ppmd, "PPMd" }, + { CompressionMethod.BZip2, "BZip2" } + }; - #endregion + #endregion internal static readonly Dictionary InForOutFormats = new Dictionary - #region InForOutFormats initialization + #region InForOutFormats initialization - { - {OutArchiveFormat.SevenZip, InArchiveFormat.SevenZip}, - {OutArchiveFormat.GZip, InArchiveFormat.GZip}, - {OutArchiveFormat.BZip2, InArchiveFormat.BZip2}, - {OutArchiveFormat.Tar, InArchiveFormat.Tar}, - {OutArchiveFormat.XZ, InArchiveFormat.XZ}, - {OutArchiveFormat.Zip, InArchiveFormat.Zip} - }; + { + { OutArchiveFormat.SevenZip, InArchiveFormat.SevenZip }, + { OutArchiveFormat.GZip, InArchiveFormat.GZip }, + { OutArchiveFormat.BZip2, InArchiveFormat.BZip2 }, + { OutArchiveFormat.Tar, InArchiveFormat.Tar }, + { OutArchiveFormat.XZ, InArchiveFormat.XZ }, + { OutArchiveFormat.Zip, InArchiveFormat.Zip } + }; - #endregion + #endregion /// /// List of archive formats corresponding to specific extensions /// private static readonly Dictionary InExtensionFormats = new Dictionary - #region InExtensionFormats initialization + #region InExtensionFormats initialization - {{"7z", InArchiveFormat.SevenZip}, - {"gz", InArchiveFormat.GZip}, - {"tar", InArchiveFormat.Tar}, - {"rar", InArchiveFormat.Rar}, - {"zip", InArchiveFormat.Zip}, - {"lzma", InArchiveFormat.Lzma}, - {"lzh", InArchiveFormat.Lzh}, - {"arj", InArchiveFormat.Arj}, - {"bz2", InArchiveFormat.BZip2}, - {"cab", InArchiveFormat.Cab}, - {"chm", InArchiveFormat.Chm}, - {"deb", InArchiveFormat.Deb}, - {"iso", InArchiveFormat.Iso}, - {"rpm", InArchiveFormat.Rpm}, - {"wim", InArchiveFormat.Wim}, - {"udf", InArchiveFormat.Udf}, - {"mub", InArchiveFormat.Mub}, - {"xar", InArchiveFormat.Xar}, - {"hfs", InArchiveFormat.Hfs}, - {"dmg", InArchiveFormat.Dmg}, - {"Z", InArchiveFormat.Lzw}, - {"xz", InArchiveFormat.XZ}, - {"flv", InArchiveFormat.Flv}, - {"swf", InArchiveFormat.Swf}, - {"exe", InArchiveFormat.PE}, - {"dll", InArchiveFormat.PE}, - {"vhd", InArchiveFormat.Vhd} - }; + { + { "7z", InArchiveFormat.SevenZip }, + { "gz", InArchiveFormat.GZip }, + { "tar", InArchiveFormat.Tar }, + { "rar", InArchiveFormat.Rar }, + { "zip", InArchiveFormat.Zip }, + { "lzma", InArchiveFormat.Lzma }, + { "lzh", InArchiveFormat.Lzh }, + { "arj", InArchiveFormat.Arj }, + { "bz2", InArchiveFormat.BZip2 }, + { "cab", InArchiveFormat.Cab }, + { "chm", InArchiveFormat.Chm }, + { "deb", InArchiveFormat.Deb }, + { "iso", InArchiveFormat.Iso }, + { "rpm", InArchiveFormat.Rpm }, + { "wim", InArchiveFormat.Wim }, + { "udf", InArchiveFormat.Udf }, + { "mub", InArchiveFormat.Mub }, + { "xar", InArchiveFormat.Xar }, + { "hfs", InArchiveFormat.Hfs }, + { "dmg", InArchiveFormat.Dmg }, + { "z", InArchiveFormat.Lzw }, + { "xz", InArchiveFormat.XZ }, + { "flv", InArchiveFormat.Flv }, + { "swf", InArchiveFormat.Swf }, + { "exe", InArchiveFormat.PE }, + { "dll", InArchiveFormat.PE }, + { "vhd", InArchiveFormat.Vhd } + }; #endregion /// - /// List of archive formats corresponding to specific signatures + /// Signatures per archive format. /// - /// Based on the information at this site. - internal static readonly Dictionary InSignatureFormats = - new Dictionary - #region InSignatureFormats initialization - - {{"37-7A-BC-AF-27-1C", InArchiveFormat.SevenZip}, - {"1F-8B-08", InArchiveFormat.GZip}, - {"75-73-74-61-72", InArchiveFormat.Tar}, - //257 byte offset - {"52-61-72-21-1A-07-00", InArchiveFormat.Rar4}, - {"52-61-72-21-1A-07-01-00", InArchiveFormat.Rar}, - {"50-4B-03-04", InArchiveFormat.Zip}, - {"5D-00-00-40-00", InArchiveFormat.Lzma}, - {"2D-6C-68", InArchiveFormat.Lzh}, - //^ 2 byte offset - {"1F-9D-90", InArchiveFormat.Lzw}, - {"60-EA", InArchiveFormat.Arj}, - {"42-5A-68", InArchiveFormat.BZip2}, - {"4D-53-43-46", InArchiveFormat.Cab}, - {"49-54-53-46", InArchiveFormat.Chm}, - {"21-3C-61-72-63-68-3E-0A-64-65-62-69-61-6E-2D-62-69-6E-61-72-79", InArchiveFormat.Deb}, - {"43-44-30-30-31", InArchiveFormat.Iso}, - //^ 0x8001, 0x8801 or 0x9001 byte offset - {"ED-AB-EE-DB", InArchiveFormat.Rpm}, - {"4D-53-57-49-4D-00-00-00", InArchiveFormat.Wim}, - {"udf", InArchiveFormat.Udf}, - {"mub", InArchiveFormat.Mub}, - {"78-61-72-21", InArchiveFormat.Xar}, - //0x400 byte offset - {"48-2B", InArchiveFormat.Hfs}, - {"FD-37-7A-58-5A", InArchiveFormat.XZ}, - {"46-4C-56", InArchiveFormat.Flv}, - {"46-57-53", InArchiveFormat.Swf}, - {"4D-5A", InArchiveFormat.PE}, - {"7F-45-4C-46", InArchiveFormat.Elf}, - {"78", InArchiveFormat.Dmg}, - {"63-6F-6E-65-63-74-69-78", InArchiveFormat.Vhd}}; - #endregion + internal static readonly Dictionary> ArchiveFormatSignatures = + new Dictionary> + #region InSignatureFormats initialization - internal static Dictionary InSignatureFormatsReversed; + { + [InArchiveFormat.Arj] = Signature_ArjArchive, + [InArchiveFormat.BZip2] = Signature_BZip2Archive, + [InArchiveFormat.Cab] = Signature_CabArchive, + [InArchiveFormat.GZip] = Signature_GZipArchive, + [InArchiveFormat.Lzh] = Signature_LzhArchive, + [InArchiveFormat.Lzma] = Signature_LzmaArchive, + [InArchiveFormat.Lzw] = Signature_LzwArchive, + [InArchiveFormat.Rar] = Signature_RarArchive, + [InArchiveFormat.Rar4] = Signature_Rar4Archive, + [InArchiveFormat.SevenZip] = Signature_SevenZipArchive, + [InArchiveFormat.Tar] = Signature_USTarArchive, + [InArchiveFormat.Xar] = Signature_XarArchive, + [InArchiveFormat.XZ] = Signature_XZArchive, + [InArchiveFormat.Zip] = Signature_ZipArchive, + }; - static Formats() - { - InSignatureFormatsReversed = new Dictionary(InSignatureFormats.Count); - - foreach (var pair in InSignatureFormats) - { - InSignatureFormatsReversed.Add(pair.Value, pair.Key); - } - } + #endregion /// /// Gets InArchiveFormat for specified archive file name @@ -571,23 +576,41 @@ static Formats() /// Archive file name /// Indicates whether to throw exceptions /// InArchiveFormat recognized by the file name extension - /// + /// public static InArchiveFormat FormatByFileName(string fileName, bool reportErrors) { - if (String.IsNullOrEmpty(fileName) && reportErrors) + var exception = FormatByFileName(fileName, out var archiveFormat); + if (exception != null) { - throw new ArgumentException("File name is null or empty string!"); + if (reportErrors) + throw exception; + return (InArchiveFormat)(-1); } - string extension = Path.GetExtension(fileName).Substring(1); - if (!InExtensionFormats.ContainsKey(extension) && reportErrors) - { - throw new ArgumentException("Extension \"" + extension + "\" is not a supported archive file name extension."); + return archiveFormat; + } + /// + /// Gets InArchiveFormat for specified archive file name + /// + /// Archive file name + /// InArchiveFormat recognized by the file name extension + /// An exception if a failure occurred; otherwise null. + internal static Exception FormatByFileName(string fileName, out InArchiveFormat archiveFormat) + { + archiveFormat = (InArchiveFormat)(-1); + if (string.IsNullOrEmpty(fileName)) + return new ArgumentException("File name is null or empty string!"); - } + string extension = Path.GetExtension(fileName); + if (!string.IsNullOrEmpty(extension)) + extension = extension.Substring(1).ToLower(); + + if (!InExtensionFormats.ContainsKey(extension)) + return new ArgumentException("Extension \"" + extension + "\" is not a supported archive file name extension."); - return InExtensionFormats[extension]; + archiveFormat = InExtensionFormats[extension]; + return null; } } #endif diff --git a/SevenZip/IEnumerableHelper.cs b/SevenZip/IEnumerableHelper.cs new file mode 100644 index 0000000..c445ddf --- /dev/null +++ b/SevenZip/IEnumerableHelper.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SevenZip +{ + public static class IEnumerableHelper + { + // from https://stackoverflow.com/a/3562370, variable names renamed. + public static int IndexOfSequence(this IEnumerable source, IEnumerable sequence, IEqualityComparer comparer = null) + { + if (comparer == null) + comparer = EqualityComparer.Default; + + var seq = sequence.ToArray(); + int positionInSource = 0; // current position in source sequence + int posInSearched = 0; // current position in searched sequence + var possibleStartIndices = new List(); // a list of possible start indices of the sequence in the source + + foreach (var item in source) + { + // Remove bad prospective matches + possibleStartIndices.RemoveAll(possibleStartIndex => !comparer.Equals(item, seq[positionInSource - possibleStartIndex])); + + // Is it the start of a prospective match ? + if (comparer.Equals(item, seq[0])) + { + possibleStartIndices.Add(positionInSource); + } + + // Does current character continues partial match ? + if (comparer.Equals(item, seq[posInSearched])) + { + posInSearched++; + // Do we have a complete match ? + if (posInSearched == seq.Length) + { + // Bingo ! + return positionInSource - seq.Length + 1; + } + } + else // Mismatch + { + // Do we have prospective matches to fall back to ? + if (possibleStartIndices.Count > 0) + { + // Yes, use the first one + int possibleStartIndex = possibleStartIndices[0]; + posInSearched = positionInSource - possibleStartIndex + 1; + } + else + { + // No, start from beginning of searched sequence + posInSearched = 0; + } + } + + positionInSource++; + } + + // No match + return -1; + } + } +} \ No newline at end of file