Skip to content

Commit

Permalink
PR #333: Handle unsupported compression methods in ZipInputStream better
Browse files Browse the repository at this point in the history
* Change ZipInputStream to use its own IsEntryCompressionMethodSupported function rather than the one in ZipEntry.

* Unit test for ZipInputStream.CanDecompressEntry being false for AES encrypted entries.

* Fix comment typo

Co-authored-by: nils måsén <[email protected]>
  • Loading branch information
Numpsy and piksel authored Aug 15, 2020
1 parent c557266 commit 83c80d2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,26 @@ public bool CanDecompressEntry
{
get
{
return (entry != null) && entry.CanDecompress;
return (entry != null) && IsEntryCompressionMethodSupported(entry) && entry.CanDecompress;
}
}

/// <summary>
/// Is the compression method for the specified entry supported?
/// </summary>
/// <remarks>
/// Uses entry.CompressionMethodForHeader so that entries of type WinZipAES will be rejected.
/// </remarks>
/// <param name="entry">the entry to check.</param>
/// <returns>true if the compression methiod is supported, false if not.</returns>
private static bool IsEntryCompressionMethodSupported(ZipEntry entry)
{
var entryCompressionMethod = entry.CompressionMethodForHeader;

return entryCompressionMethod == CompressionMethod.Deflated ||
entryCompressionMethod == CompressionMethod.Stored;
}

/// <summary>
/// Advances to the next entry in the archive
/// </summary>
Expand Down Expand Up @@ -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);
}
Expand Down
34 changes: 34 additions & 0 deletions test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,40 @@ public void ZipFileAESReadWithEmptyPassword()
}
}

/// <summary>
/// ZipInputStream can't decrypt AES encrypted entries, but it should report that to the caller
/// rather than just failing.
/// </summary>
[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<ZipException>(() => inputStream.ReadByte());
}
}
}

private static readonly string[] possible7zPaths = new[] {
// Check in PATH
"7z", "7za",
Expand Down

0 comments on commit 83c80d2

Please sign in to comment.