diff --git a/SharpCompress.Test/Rar/RarArchiveTests.cs b/SharpCompress.Test/Rar/RarArchiveTests.cs index 59b71fbf..9e5977d7 100644 --- a/SharpCompress.Test/Rar/RarArchiveTests.cs +++ b/SharpCompress.Test/Rar/RarArchiveTests.cs @@ -13,24 +13,24 @@ namespace SharpCompress.Test [TestMethod] public void Rar_EncryptedFileAndHeader_Archive() { - ReadRar("Rar.encrypted_filesAndHeader.rar", "test"); + ReadRarPassword("Rar.encrypted_filesAndHeader.rar", "test"); } [TestMethod] public void Rar_EncryptedFileOnly_Archive() { - ReadRar("Rar.encrypted_filesOnly.rar", "test"); + ReadRarPassword("Rar.encrypted_filesOnly.rar", "test"); } [TestMethod] public void Rar_Encrypted_Archive() { - ReadRar("Encrypted.rar", "test"); + ReadRarPassword("Encrypted.rar", "test"); } - private void ReadRar(string testArchive, string password) + private void ReadRarPassword(string testArchive, string password) { ResetScratch(); using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, testArchive))) @@ -47,6 +47,28 @@ namespace SharpCompress.Test } VerifyFiles(); } + + [TestMethod] + [ExpectedException(typeof(InvalidFormatException))] + public void Rar_Multi_Archive_Encrypted() + { + ArchiveFileReadPassword("EncryptedParts.part01.rar", "test"); + } + + protected void ArchiveFileReadPassword(string archiveName, string password) + { + ResetScratch(); + using (var archive = RarArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, archiveName), Options.None, password)) + { + foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) + { + entry.WriteToDirectory(SCRATCH_FILES_PATH, + ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite); + } + } + VerifyFiles(); + } + [TestMethod] public void Rar_None_ArchiveStreamRead() { @@ -59,7 +81,6 @@ namespace SharpCompress.Test ArchiveStreamRead("Rar.rar"); } - [TestMethod] public void Rar_test_invalid_exttime_ArchiveStreamRead() { diff --git a/SharpCompress.Test/Rar/RarReaderTests.cs b/SharpCompress.Test/Rar/RarReaderTests.cs index 0f4b2161..349b72c3 100644 --- a/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/SharpCompress.Test/Rar/RarReaderTests.cs @@ -33,6 +33,29 @@ namespace SharpCompress.Test VerifyFiles(); } + //[TestMethod] + public void Rar_Multi_Reader_Encrypted() + { + var testArchives = new string[] { "EncryptedParts.part01.rar", + "EncryptedParts.part02.rar", + "EncryptedParts.part03.rar", + "EncryptedParts.part04.rar", + "EncryptedParts.part05.rar", + "EncryptedParts.part06.rar"}; + + + ResetScratch(); + using (var reader = RarReader.Open(testArchives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) + .Select(p => File.OpenRead(p)))) + { + while (reader.MoveToNextEntry()) + { + reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite); + } + } + VerifyFiles(); + } + [TestMethod] public void Rar_Multi_Reader_Delete_Files() { diff --git a/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs b/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs index fb3b3171..aba7c2d4 100644 --- a/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs +++ b/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs @@ -120,6 +120,10 @@ namespace SharpCompress.Common.Rar.Headers if (IsEncrypted) { + if (Password == null) + { + throw new CryptographicException("Encrypted Rar archive has no password specified."); + } reader.SkipQueue(); byte[] salt = reader.ReadBytes(8); reader.InitializeAes(salt); diff --git a/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs b/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs index cac5460f..c0add4e5 100644 --- a/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs +++ b/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs @@ -67,27 +67,33 @@ namespace SharpCompress.Compressor.Rar public override int Read(byte[] buffer, int offset, int count) { int totalRead = 0; - while (count > 0) + int currentOffset = offset; + int currentCount = count; + while (currentCount > 0) { - int readSize = count; - if (count > maxPosition - currentPosition) + int readSize = currentCount; + if (currentCount > maxPosition - currentPosition) { readSize = (int) (maxPosition - currentPosition); } - int read = currentStream.Read(buffer, offset, readSize); + int read = currentStream.Read(buffer, currentOffset, readSize); if (read < 0) { throw new EndOfStreamException(); } currentPosition += read; - offset += read; - count -= read; + currentOffset += read; + currentCount -= read; totalRead += read; if (((maxPosition - currentPosition) == 0) && filePartEnumerator.Current.FileHeader.FileFlags.HasFlag(FileFlags.SPLIT_AFTER)) { + if (filePartEnumerator.Current.FileHeader.Salt != null) + { + throw new InvalidFormatException("Sharpcompress currently does not support multi-volume decryption."); + } string fileName = filePartEnumerator.Current.FileHeader.FileName; if (!filePartEnumerator.MoveNext()) { diff --git a/SharpCompress/Utility.cs b/SharpCompress/Utility.cs index 71affc7e..87ae9523 100644 --- a/SharpCompress/Utility.cs +++ b/SharpCompress/Utility.cs @@ -407,7 +407,7 @@ namespace SharpCompress public static long TransferTo(this Stream source, Stream destination) { - byte[] array = new byte[4096]; + byte[] array = new byte[81920]; int count; long total = 0; while ((count = source.Read(array, 0, array.Length)) != 0) diff --git a/TestArchives/Archives/EncryptedParts.part01.rar b/TestArchives/Archives/EncryptedParts.part01.rar new file mode 100644 index 00000000..f6608e36 Binary files /dev/null and b/TestArchives/Archives/EncryptedParts.part01.rar differ diff --git a/TestArchives/Archives/EncryptedParts.part02.rar b/TestArchives/Archives/EncryptedParts.part02.rar new file mode 100644 index 00000000..1020dd0f Binary files /dev/null and b/TestArchives/Archives/EncryptedParts.part02.rar differ diff --git a/TestArchives/Archives/EncryptedParts.part03.rar b/TestArchives/Archives/EncryptedParts.part03.rar new file mode 100644 index 00000000..b8fd5df8 Binary files /dev/null and b/TestArchives/Archives/EncryptedParts.part03.rar differ diff --git a/TestArchives/Archives/EncryptedParts.part04.rar b/TestArchives/Archives/EncryptedParts.part04.rar new file mode 100644 index 00000000..af28c7ec Binary files /dev/null and b/TestArchives/Archives/EncryptedParts.part04.rar differ diff --git a/TestArchives/Archives/EncryptedParts.part05.rar b/TestArchives/Archives/EncryptedParts.part05.rar new file mode 100644 index 00000000..fb371b43 Binary files /dev/null and b/TestArchives/Archives/EncryptedParts.part05.rar differ diff --git a/TestArchives/Archives/EncryptedParts.part06.rar b/TestArchives/Archives/EncryptedParts.part06.rar new file mode 100644 index 00000000..9aa12437 Binary files /dev/null and b/TestArchives/Archives/EncryptedParts.part06.rar differ