diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs index b9c8d8c35..6c210931f 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs @@ -131,10 +131,26 @@ public bool CanDecompressEntry { get { - return (entry != null) && entry.CanDecompress; + return (entry != null) && IsEntryCompressionMethodSupported(entry) && entry.CanDecompress; } } + /// + /// Is the compression method for the specified entry supported? + /// + /// + /// Uses entry.CompressionMethodForHeader so that entries of type WinZipAES will be rejected. + /// + /// the entry to check. + /// true if the compression methiod is supported, false if not. + private static bool IsEntryCompressionMethodSupported(ZipEntry entry) + { + var entryCompressionMethod = entry.CompressionMethodForHeader; + + return entryCompressionMethod == CompressionMethod.Deflated || + entryCompressionMethod == CompressionMethod.Stored; + } + /// /// Advances to the next entry in the archive /// @@ -271,7 +287,7 @@ public ZipEntry GetNextEntry() } // Determine how to handle reading of data if this is attempted. - if (entry.IsCompressionMethodSupported()) + if (IsEntryCompressionMethodSupported(entry)) { internalReader = new ReadDataHandler(InitialRead); } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs index f9c988df1..938c062fe 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs @@ -399,6 +399,40 @@ public void ZipFileAESReadWithEmptyPassword() } } + /// + /// ZipInputStream can't decrypt AES encrypted entries, but it should report that to the caller + /// rather than just failing. + /// + [Test] + [Category("Zip")] + public void ZipinputStreamShouldGracefullyFailWithAESStreams() + { + string password = "password"; + + using (var memoryStream = new MemoryStream()) + { + // Try to create a zip stream + WriteEncryptedZipToStream(memoryStream, password, 256); + + // reset + memoryStream.Seek(0, SeekOrigin.Begin); + + // Try to read + using (var inputStream = new ZipInputStream(memoryStream)) + { + inputStream.Password = password; + var entry = inputStream.GetNextEntry(); + Assert.That(entry.AESKeySize, Is.EqualTo(256), "Test entry should be AES256 encrypted."); + + // CanDecompressEntry should be false. + Assert.That(inputStream.CanDecompressEntry, Is.False, "CanDecompressEntry should be false for AES encrypted entries"); + + // Should throw on read. + Assert.Throws(() => inputStream.ReadByte()); + } + } + } + private static readonly string[] possible7zPaths = new[] { // Check in PATH "7z", "7za",