From a7d3b100a0b30dd51b69a3e9295d321d180feec9 Mon Sep 17 00:00:00 2001 From: Jay Sanati Date: Fri, 23 Oct 2026 22:36:26 -0700 Subject: [PATCH] Report the codec, not 7zAES, as an encrypted 7z entry's CompressionType 7-Zip writes 7zAES as the first coder of an encrypted folder, in front of the codec. SevenZipFilePart.GetCompression() looked at the first coder only, so CompressionType threw InvalidFormatException for every entry of a 7-Zip-made encrypted archive. Skip the AES filter and report the first real coder. Co-Authored-By: Claude Opus 5.5 --- .../Common/SevenZip/SevenZipFilePart.cs | 6 ++++- .../SevenZip/SevenZipArchiveTests.cs | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs index 2b3f6af3..2ab660e6 100644 --- a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs +++ b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs @@ -119,7 +119,11 @@ internal class SevenZipFilePart : FilePart return CompressionType.None; } - var coder = Folder.NotNull()._coders.First(); + // 7zAES is a filter in front of the codec (7-Zip writes it as coder 0), so it says + // nothing about the compression; report the first real coder instead. + var coder = + Folder.NotNull()._coders.FirstOrDefault(c => c._methodId._id != CMethodId.K_AES_ID) + ?? throw new InvalidFormatException(); return coder._methodId._id switch { K_COPY => CompressionType.None, diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs index dc3b1c93..05aea802 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs @@ -105,6 +105,29 @@ public class SevenZipArchiveTests : ArchiveTests new SevenZipFactory() ); + [Theory] + [InlineData("7Zip.LZMA.Aes.7z")] + [InlineData("7Zip.LZMA2.Aes.7z")] + public void SevenZipArchive_Aes_ReportsCompressionType(string testArchive) + { + // 7-Zip writes 7zAES as the folder's first coder, in front of the codec. + using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, testArchive)); + using var archive = SevenZipArchive.OpenArchive( + stream, + ReaderOptions.ForExternalStream with + { + Password = "testpassword", + } + ); + var files = archive.Entries.Where(entry => !entry.IsDirectory && entry.Size > 0).ToList(); + Assert.NotEmpty(files); + foreach (var entry in files) + { + Assert.True(entry.IsEncrypted, entry.Key); + Assert.Equal(CompressionType.LZMA, entry.CompressionType); + } + } + [Fact] public void SevenZipArchive_LZMA2AES_StreamRead() => ArchiveStreamRead(