From 7ac1fda74e1950562015f8769a0eeb65f27314cf Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Sat, 8 May 2021 17:19:17 +0100 Subject: [PATCH] #579: Implement very simple ReadAsync in ZipAESStream * add an extra unit test for doing an async read on a ZipFile InputStream * Implement ReadAsync in ZipAESStream, extra simple version --- .../Encryption/ZipAESStream.cs | 9 +++ .../Zip/ZipEncryptionHandling.cs | 65 ++++++++++++++++--- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs index 4bf01300b..80ce0b4ab 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs @@ -1,6 +1,8 @@ using System; using System.IO; using System.Security.Cryptography; +using System.Threading; +using System.Threading.Tasks; using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Zip; @@ -91,6 +93,13 @@ public override int Read(byte[] buffer, int offset, int count) return nBytes; } + /// + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + var readCount = Read(buffer, offset, count); + return Task.FromResult(readCount); + } + // Read data from the underlying stream and decrypt it private int ReadAndTransform(byte[] buffer, int offset, int count) { diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs index 34dde202b..f3a240d30 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text; using ICSharpCode.SharpZipLib.Tests.TestSupport; +using System.Threading.Tasks; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -149,14 +150,9 @@ public void ZipFileStoreAes() { string password = "password"; - using (var memoryStream = new MemoryStream()) + // Make an encrypted zip file + using (var memoryStream = MakeAESEncryptedZipStream(password)) { - // Try to create a zip stream - WriteEncryptedZipToStream(memoryStream, password, 256, CompressionMethod.Stored); - - // reset - memoryStream.Seek(0, SeekOrigin.Begin); - // try to read it var zipFile = new ZipFile(memoryStream, leaveOpen: true) { @@ -180,6 +176,57 @@ public void ZipFileStoreAes() } } + /// + /// As , but with Async reads + /// + [Test] + [Category("Encryption")] + [Category("Zip")] + public async Task ZipFileStoreAesAsync() + { + string password = "password"; + + // Make an encrypted zip file + using (var memoryStream = MakeAESEncryptedZipStream(password)) + { + // try to read it + var zipFile = new ZipFile(memoryStream, leaveOpen: true) + { + Password = password + }; + + foreach (ZipEntry entry in zipFile) + { + // Should be stored rather than deflated + Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.Stored), "Entry should be stored"); + + using (var zis = zipFile.GetInputStream(entry)) + { + using (var inputStream = zipFile.GetInputStream(entry)) + using (var sr = new StreamReader(zis, Encoding.UTF8)) + { + var content = await sr.ReadToEndAsync(); + Assert.That(content, Is.EqualTo(DummyDataString), "Decompressed content does not match input data"); + } + } + } + } + } + + // Shared helper for the ZipFileStoreAes tests + private static Stream MakeAESEncryptedZipStream(string password) + { + var memoryStream = new MemoryStream(); + + // Try to create a zip stream + WriteEncryptedZipToStream(memoryStream, password, 256, CompressionMethod.Stored); + + // reset + memoryStream.Seek(0, SeekOrigin.Begin); + + return memoryStream; + } + /// /// Test using AES encryption on a file whose contents are Stored rather than deflated /// @@ -469,7 +516,7 @@ public void ZipinputStreamShouldGracefullyFailWithAESStreams() } } - public void WriteEncryptedZipToStream(Stream stream, string password, int keySize, CompressionMethod compressionMethod = CompressionMethod.Deflated) + public static void WriteEncryptedZipToStream(Stream stream, string password, int keySize, CompressionMethod compressionMethod = CompressionMethod.Deflated) { using (var zs = new ZipOutputStream(stream)) { @@ -496,7 +543,7 @@ public void WriteEncryptedZipToStream(Stream stream, int entryCount, string pass } } - private void AddEncrypedEntryToStream(ZipOutputStream zipOutputStream, string entryName, int keySize, CompressionMethod compressionMethod) + private static void AddEncrypedEntryToStream(ZipOutputStream zipOutputStream, string entryName, int keySize, CompressionMethod compressionMethod) { ZipEntry zipEntry = new ZipEntry(entryName) {