Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the behaviour of ZipInputStream when reading zip entries with unsupported compression methods #333

Merged
merged 3 commits into from
Aug 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -399,6 +399,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