From 44174e7b034de6a29462f569f464a3e8b9b095fb Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 20 Jan 2026 09:07:57 +0000 Subject: [PATCH] some fixes --- src/SharpCompress/Archives/Rar/RarArchive.cs | 4 +- .../Archives/Rar/RarArchiveEntryFactory.cs | 44 +++++++++++++++++++ .../Common/Rar/AsyncRarCryptoBinaryReader.cs | 4 +- .../Common/Rar/RarCryptoBinaryReader.cs | 4 +- .../Rar/RarArchiveAsyncTests.cs | 6 +-- 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs index 25229d65..efd26487 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.cs @@ -24,7 +24,7 @@ public interface IRarArchive : IArchive, IRarArchiveCommon { } public interface IRarAsyncArchive : IAsyncArchive, IRarArchiveCommon { } -public partial class RarArchive : AbstractArchive, IRarArchive +public partial class RarArchive : AbstractArchive, IRarArchive, IRarAsyncArchive { private bool _disposed; internal Lazy UnpackV2017 { get; } = @@ -64,6 +64,8 @@ public partial class RarArchive : AbstractArchive, I protected override IEnumerable LoadEntries(IEnumerable volumes) => RarArchiveEntryFactory.GetEntries(this, volumes, ReaderOptions); + protected override IAsyncEnumerable LoadEntriesAsync(IAsyncEnumerable volumes) => + RarArchiveEntryFactory.GetEntriesAsync(this, volumes, ReaderOptions); protected override IEnumerable LoadVolumes(SourceStream sourceStream) { diff --git a/src/SharpCompress/Archives/Rar/RarArchiveEntryFactory.cs b/src/SharpCompress/Archives/Rar/RarArchiveEntryFactory.cs index ec4ace7c..facb473c 100644 --- a/src/SharpCompress/Archives/Rar/RarArchiveEntryFactory.cs +++ b/src/SharpCompress/Archives/Rar/RarArchiveEntryFactory.cs @@ -17,6 +17,17 @@ internal static class RarArchiveEntryFactory } } + private static async IAsyncEnumerable GetFilePartsAsync(IAsyncEnumerable parts) + { + await foreach (var rarPart in parts) + { + await foreach (var fp in rarPart.ReadFilePartsAsync()) + { + yield return fp; + } + } + } + private static IEnumerable> GetMatchedFileParts( IEnumerable parts ) @@ -38,6 +49,27 @@ internal static class RarArchiveEntryFactory } } + private static async IAsyncEnumerable> GetMatchedFilePartsAsync( + IAsyncEnumerable parts + ) + { + var groupedParts = new List(); + await foreach (var fp in GetFilePartsAsync(parts)) + { + groupedParts.Add(fp); + + if (!fp.FileHeader.IsSplitAfter) + { + yield return groupedParts; + groupedParts = new List(); + } + } + if (groupedParts.Count > 0) + { + yield return groupedParts; + } + } + internal static IEnumerable GetEntries( RarArchive archive, IEnumerable rarParts, @@ -49,4 +81,16 @@ internal static class RarArchiveEntryFactory yield return new RarArchiveEntry(archive, groupedParts, readerOptions); } } + + internal static async IAsyncEnumerable GetEntriesAsync( + RarArchive archive, + IAsyncEnumerable rarParts, + ReaderOptions readerOptions + ) + { + await foreach (var groupedParts in GetMatchedFilePartsAsync(rarParts)) + { + yield return new RarArchiveEntry(archive, groupedParts, readerOptions); + } + } } diff --git a/src/SharpCompress/Common/Rar/AsyncRarCryptoBinaryReader.cs b/src/SharpCompress/Common/Rar/AsyncRarCryptoBinaryReader.cs index d938498d..47d053f2 100644 --- a/src/SharpCompress/Common/Rar/AsyncRarCryptoBinaryReader.cs +++ b/src/SharpCompress/Common/Rar/AsyncRarCryptoBinaryReader.cs @@ -24,7 +24,7 @@ internal sealed class AsyncRarCryptoBinaryReader : AsyncRarCrcBinaryReader var binary = new AsyncRarCryptoBinaryReader(stream); if (salt == null) { - salt = await binary.ReadBytesAsync(EncryptionConstV5.SIZE_SALT30); + salt = await binary.ReadBytesAsyncBase(EncryptionConstV5.SIZE_SALT30); binary._readCount += EncryptionConstV5.SIZE_SALT30; } binary._rijndael = new BlockTransformer(cryptKey.Transformer(salt)); @@ -51,6 +51,8 @@ internal sealed class AsyncRarCryptoBinaryReader : AsyncRarCrcBinaryReader return bytes[0]; } + private ValueTask ReadBytesAsyncBase(int count) => base.ReadBytesAsync(count); + public override async ValueTask ReadBytesAsync( int count, CancellationToken cancellationToken = default diff --git a/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs b/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs index 0b60938c..7e288283 100644 --- a/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs +++ b/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs @@ -23,7 +23,7 @@ internal sealed class RarCryptoBinaryReader : RarCrcBinaryReader var binary = new RarCryptoBinaryReader(stream); if (salt == null) { - salt = binary.ReadBytes(EncryptionConstV5.SIZE_SALT30); + salt = binary.ReadBytesBase(EncryptionConstV5.SIZE_SALT30); binary._readCount += EncryptionConstV5.SIZE_SALT30; } binary._rijndael = new BlockTransformer(cryptKey.Transformer(salt)); @@ -46,6 +46,8 @@ internal sealed class RarCryptoBinaryReader : RarCrcBinaryReader public override byte[] ReadBytes(int count) => ReadAndDecryptBytes(count); + private byte[] ReadBytesBase(int count) => base.ReadBytes(count); + private byte[] ReadAndDecryptBytes(int count) { var queueSize = _data.Count; diff --git a/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs index 479a5655..7b2fbe7e 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs @@ -68,14 +68,14 @@ public class RarArchiveAsyncTests : ArchiveTests private async ValueTask ReadRarPasswordAsync(string testArchive, string? password) { using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, testArchive))) - using ( - var archive = RarArchive.OpenArchive( + await using ( + var archive = RarArchive.OpenAsyncArchive( stream, new ReaderOptions { Password = password, LeaveStreamOpen = true } ) ) { - foreach (var entry in archive.Entries) + await foreach (var entry in archive.EntriesAsync) { if (!entry.IsDirectory) {