From 83a2e6fb8de033f7eecf31c8ed698512e2b8ea3c Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 2 Oct 2026 13:51:35 +0100 Subject: [PATCH] use arraypool --- src/SharpCompress/Common/Rar/RarVolume.cs | 49 +++++++++++++++---- .../Rar/RarArchiveAsyncTests.cs | 21 ++++++++ .../SharpCompress.Test/Rar/RarArchiveTests.cs | 11 +++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/SharpCompress/Common/Rar/RarVolume.cs b/src/SharpCompress/Common/Rar/RarVolume.cs index 1b7de043..7c1d0221 100644 --- a/src/SharpCompress/Common/Rar/RarVolume.cs +++ b/src/SharpCompress/Common/Rar/RarVolume.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; @@ -66,9 +67,25 @@ public abstract class RarVolume : Volume var fh = (FileHeader)header; if (fh.FileName == "CMT") { - var buffer = new byte[fh.CompressedSize]; - fh.PackedStream.NotNull().ReadFully(buffer); - Comment = Encoding.UTF8.GetString(buffer, 0, buffer.Length - 1); + var commentSize = checked((int)fh.CompressedSize); + var buffer = ArrayPool.Shared.Rent(commentSize); + try + { + // Pooled buffers can be larger than the comment payload. + if ( + !fh + .PackedStream.NotNull() + .ReadFully(buffer.AsSpan(0, commentSize)) + ) + { + throw new EndOfStreamException(); + } + Comment = Encoding.UTF8.GetString(buffer, 0, commentSize - 1); + } + finally + { + ArrayPool.Shared.Return(buffer); + } } } break; @@ -115,12 +132,26 @@ public abstract class RarVolume : Volume var fh = (FileHeader)header; if (fh.FileName == "CMT") { - var buffer = new byte[fh.CompressedSize]; - await fh - .PackedStream.NotNull() - .ReadFullyAsync(buffer, cancellationToken) - .ConfigureAwait(false); - Comment = Encoding.UTF8.GetString(buffer, 0, buffer.Length - 1); + var commentSize = checked((int)fh.CompressedSize); + var buffer = ArrayPool.Shared.Rent(commentSize); + try + { + // Pooled buffers can be larger than the comment payload. + if ( + !await fh + .PackedStream.NotNull() + .ReadFullyAsync(buffer, 0, commentSize, cancellationToken) + .ConfigureAwait(false) + ) + { + throw new EndOfStreamException(); + } + Comment = Encoding.UTF8.GetString(buffer, 0, commentSize - 1); + } + finally + { + ArrayPool.Shared.Return(buffer); + } } } break; diff --git a/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs index b3cd79bd..afe0027a 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs @@ -1,9 +1,11 @@ using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; using SharpCompress.Archives; using SharpCompress.Archives.Rar; using SharpCompress.Common; +using SharpCompress.Common.Rar; using SharpCompress.Compressors.LZMA.Utilities; using SharpCompress.Readers; using SharpCompress.Test.Mocks; @@ -13,6 +15,25 @@ namespace SharpCompress.Test.Rar; public class RarArchiveAsyncTests : ArchiveTests { + [Fact] + public async ValueTask Rar5_Comment_Archive_Async() + { + await using var archive = await RarArchive.OpenAsyncArchive( + Path.Combine(TEST_ARCHIVES_PATH, "Rar5.comment.rar"), + cancellationToken: CancellationToken.None + ); + var entryCount = 0; + await foreach (var entry in archive.EntriesAsync.WithCancellation(CancellationToken.None)) + { + entryCount++; + } + Assert.True(entryCount > 0); + await foreach (var volume in archive.VolumesAsync.WithCancellation(CancellationToken.None)) + { + Assert.Equal("This is another comment\n", ((RarVolume)volume).Comment); + } + } + [Theory] [InlineData("Rar15.rar")] [InlineData("Rar2.rar")] diff --git a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs index 65f5a0d2..968d567a 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs @@ -4,6 +4,7 @@ using System.Linq; using SharpCompress.Archives; using SharpCompress.Archives.Rar; using SharpCompress.Common; +using SharpCompress.Common.Rar; using SharpCompress.Compressors.LZMA.Utilities; using SharpCompress.Readers; using SharpCompress.Test.Mocks; @@ -13,6 +14,16 @@ namespace SharpCompress.Test.Rar; public class RarArchiveTests : ArchiveTests { + [Fact] + public void Rar5_Comment_Archive() + { + using var archive = RarArchive.OpenArchive( + Path.Combine(TEST_ARCHIVES_PATH, "Rar5.comment.rar") + ); + Assert.NotEmpty(archive.Entries); + Assert.Equal("This is another comment\n", ((RarVolume)archive.Volumes.First()).Comment); + } + [Theory] [InlineData("Rar15.rar")] [InlineData("Rar2.rar")]