From 1a452acd1c112d1f5d496d61820455071f163d2c Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Wed, 14 May 2025 10:27:18 +0200 Subject: [PATCH 1/6] implement ExtractAllEntries for multipart rar files --- src/SharpCompress/Archives/Rar/RarArchive.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs index 6a5c9781..d84d0edc 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.cs @@ -67,6 +67,16 @@ public class RarArchive : AbstractArchive protected override IReader CreateReaderForSolidExtraction() { + if (this.IsMultipartVolume()) + { + var streams = Volumes.Select(volume => + { + volume.Stream.Position = 0; + return volume.Stream; + }); + return RarReader.Open(streams, ReaderOptions); + } + var stream = Volumes.First().Stream; stream.Position = 0; return RarReader.Open(stream, ReaderOptions); From c0cd9988361218a5ea0d9ec0ed6b47ea6733b74b Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Wed, 14 May 2025 10:27:30 +0200 Subject: [PATCH 2/6] add failing test --- tests/SharpCompress.Test/Rar/RarReaderTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index 5d3c0e64..101dd6a9 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -1,6 +1,8 @@ using System; +using System.Collections; using System.IO; using System.Linq; +using SharpCompress.Archives.Rar; using SharpCompress.Common; using SharpCompress.Readers; using SharpCompress.Readers.Rar; @@ -418,4 +420,16 @@ public class RarReaderTests : ReaderTests CompressionType.Rar ) ); + + [Fact] + public void Rar_Iterate_Multipart() + { + var expectedOrder = new Stack(new[] {"Failure", "jpg", "exe", "Empty", "тест.txt", Path.Combine("jpg", "test.jpg"), Path.Combine("exe", "test.exe")}); + using var archive = RarArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part01.rar")); + using var reader = archive.ExtractAllEntries(); + while (reader.MoveToNextEntry()) + { + Assert.Equal(expectedOrder.Pop(), reader.Entry.Key); + } + } } From a3570a568df1ab093207ac0737ef84e049f4930d Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Wed, 14 May 2025 10:27:58 +0200 Subject: [PATCH 3/6] fix AbstractReader.Skip for multipart files --- src/SharpCompress/Readers/AbstractReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index ac4e1784..fc6e3d1c 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -131,7 +131,7 @@ public abstract class AbstractReader : IReader, IReaderExtracti { var part = Entry.Parts.First(); - if (!Entry.IsSolid && Entry.CompressedSize > 0) + if (!Entry.IsSplitAfter && !Entry.IsSolid && Entry.CompressedSize > 0) { //not solid and has a known compressed size then we can skip raw bytes. var rawStream = part.GetRawStream(); From 7989ab2e281cc760c712e5b4ce26f748583b1fcd Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Wed, 14 May 2025 11:18:41 +0200 Subject: [PATCH 4/6] modify now-broken test This test tested that skipping over entries using the reader interface for an encrypted multi-volume rar archive worked. However reading those entries doesn't work and the skipping was also not working properly so I believe it's fine to "break" this functionality. --- .../SharpCompress.Test/Rar/RarReaderTests.cs | 45 +++++-------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index 101dd6a9..84f0ada7 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -330,43 +330,18 @@ public class RarReaderTests : ReaderTests } [Fact] - public void Rar_NullReference() + public void Rar_SkipEncryptedFilesWithoutPassword() { + using var stream = File.OpenRead( + Path.Combine(TEST_ARCHIVES_PATH, "Rar.encrypted_filesOnly.rar") + ); + using var reader = ReaderFactory.Open( + stream, + new ReaderOptions { LookForHeader = true } + ); + while (reader.MoveToNextEntry()) { - var archives = new[] - { - "Rar.EncryptedParts.part01.rar", - "Rar.EncryptedParts.part02.rar", - "Rar.EncryptedParts.part03.rar", - "Rar.EncryptedParts.part04.rar", - "Rar.EncryptedParts.part05.rar", - "Rar.EncryptedParts.part06.rar", - }; - - using var reader = RarReader.Open( - archives - .Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) - .Select(p => File.OpenRead(p)), - new ReaderOptions { Password = "test" } - ); - while (reader.MoveToNextEntry()) - { - // - } - } - - { - using var stream = File.OpenRead( - Path.Combine(TEST_ARCHIVES_PATH, "Rar.encrypted_filesOnly.rar") - ); - using var reader = ReaderFactory.Open( - stream, - new ReaderOptions { LookForHeader = true } - ); - while (reader.MoveToNextEntry()) - { - // - } + // } } From 6e51967993df5298ec2ffce3978d35366a8657d4 Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Wed, 14 May 2025 11:42:52 +0200 Subject: [PATCH 5/6] format --- .../SharpCompress.Test/Rar/RarReaderTests.cs | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index 84f0ada7..8fb69618 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -335,10 +335,7 @@ public class RarReaderTests : ReaderTests using var stream = File.OpenRead( Path.Combine(TEST_ARCHIVES_PATH, "Rar.encrypted_filesOnly.rar") ); - using var reader = ReaderFactory.Open( - stream, - new ReaderOptions { LookForHeader = true } - ); + using var reader = ReaderFactory.Open(stream, new ReaderOptions { LookForHeader = true }); while (reader.MoveToNextEntry()) { // @@ -399,8 +396,21 @@ public class RarReaderTests : ReaderTests [Fact] public void Rar_Iterate_Multipart() { - var expectedOrder = new Stack(new[] {"Failure", "jpg", "exe", "Empty", "тест.txt", Path.Combine("jpg", "test.jpg"), Path.Combine("exe", "test.exe")}); - using var archive = RarArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part01.rar")); + var expectedOrder = new Stack( + new[] + { + "Failure", + "jpg", + "exe", + "Empty", + "тест.txt", + Path.Combine("jpg", "test.jpg"), + Path.Combine("exe", "test.exe"), + } + ); + using var archive = RarArchive.Open( + Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part01.rar") + ); using var reader = archive.ExtractAllEntries(); while (reader.MoveToNextEntry()) { From 619d98749292c53545d5ee3215cf8fae75cbfa88 Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Mon, 2 Jun 2025 21:24:38 +0200 Subject: [PATCH 6/6] fix possible out of bounds access due to unsanitized nSelectors usage --- src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs index a467942f..cf006dbc 100644 --- a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs +++ b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs @@ -542,9 +542,14 @@ internal class CBZip2InputStream : Stream { j++; } - selectorMtf[i] = (char)j; + if (i < BZip2Constants.MAX_SELECTORS) + { + selectorMtf[i] = (char)j; + } } + nSelectors = Math.Min(nSelectors, BZip2Constants.MAX_SELECTORS); + /* Undo the MTF values for the selectors. */ { var pos = new char[BZip2Constants.N_GROUPS];