From a55f226a0bea2640b924f26ee3459c17795d506c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sat, 9 Oct 2021 17:50:14 +0200 Subject: [PATCH] test: repeatability and refactoring --- .../BZip2/Bzip2Tests.cs | 37 +- .../Base/InflaterDeflaterTests.cs | 61 ++-- .../GZip/GZipTests.cs | 148 +++----- .../Tar/TarArchiveTests.cs | 5 +- .../Tar/TarTests.cs | 230 ++++++------ .../TestSupport/StringTesting.cs | 41 +-- .../TestSupport/Utils.cs | 285 +++++++++------ .../Zip/FastZipHandling.cs | 223 ++++++------ .../Zip/StreamHandling.cs | 190 +++++----- .../Zip/ZipFileHandling.cs | 335 ++++++++---------- 10 files changed, 719 insertions(+), 836 deletions(-) diff --git a/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs b/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs index 8d6febc1b..62d5a7874 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs @@ -1,7 +1,6 @@ using ICSharpCode.SharpZipLib.BZip2; using ICSharpCode.SharpZipLib.Tests.TestSupport; using NUnit.Framework; -using System; using System.IO; namespace ICSharpCode.SharpZipLib.Tests.BZip2 @@ -24,34 +23,30 @@ public void BasicRoundTrip() { var ms = new MemoryStream(); var outStream = new BZip2OutputStream(ms); + + var buf = Utils.GetDummyBytes(size: 10000, RandomSeed); - byte[] buf = new byte[10000]; - var rnd = new Random(RandomSeed); - rnd.NextBytes(buf); - - outStream.Write(buf, 0, buf.Length); + outStream.Write(buf, offset: 0, buf.Length); outStream.Close(); ms = new MemoryStream(ms.GetBuffer()); - ms.Seek(0, SeekOrigin.Begin); + ms.Seek(offset: 0, SeekOrigin.Begin); - using (BZip2InputStream inStream = new BZip2InputStream(ms)) + using BZip2InputStream inStream = new BZip2InputStream(ms); + var buf2 = new byte[buf.Length]; + var pos = 0; + while (true) { - byte[] buf2 = new byte[buf.Length]; - int pos = 0; - while (true) + var numRead = inStream.Read(buf2, pos, count: 4096); + if (numRead <= 0) { - int numRead = inStream.Read(buf2, pos, 4096); - if (numRead <= 0) - { - break; - } - pos += numRead; + break; } + pos += numRead; + } - for (int i = 0; i < buf.Length; ++i) - { - Assert.AreEqual(buf2[i], buf[i]); - } + for (var i = 0; i < buf.Length; ++i) + { + Assert.AreEqual(buf2[i], buf[i]); } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs index e6e3c4125..9df9319b4 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs @@ -60,20 +60,10 @@ private MemoryStream Deflate(byte[] data, int level, bool zlib) return memoryStream; } - private static byte[] GetRandomTestData(int size) - { - byte[] buffer = new byte[size]; - var rnd = new Random(RandomSeed); - rnd.NextBytes(buffer); - - return buffer; - } - private void RandomDeflateInflate(int size, int level, bool zlib) { - byte[] buffer = GetRandomTestData(size); - - MemoryStream ms = Deflate(buffer, level, zlib); + var buffer = Utils.GetDummyBytes(size, RandomSeed); + var ms = Deflate(buffer, level, zlib); Inflate(ms, buffer, level, zlib); } @@ -130,9 +120,8 @@ private async Task DeflateAsync(byte[] data, int level, bool zlib) private async Task RandomDeflateInflateAsync(int size, int level, bool zlib) { - byte[] buffer = GetRandomTestData(size); - - MemoryStream ms = await DeflateAsync(buffer, level, zlib); + var buffer = Utils.GetDummyBytes(size, RandomSeed); + var ms = await DeflateAsync(buffer, level, zlib); await InflateAsync(ms, buffer, level, zlib); } @@ -179,24 +168,21 @@ public void InflateDeflateZlib([Range(0, 9)] int level) [Category("Async")] public async Task InflateDeflateZlibAsync([Range(0, 9)] int level) { - await RandomDeflateInflateAsync(100000, level, true); + await RandomDeflateInflateAsync(size: 100000, level, zlib: true); } private delegate void RunCompress(byte[] buffer); - private int runLevel; - private bool runZlib; - private long runCount; - private readonly Random runRandom = new Random(RandomSeed); + private int _runLevel; + private bool _runZlib; private void DeflateAndInflate(byte[] buffer) { - ++runCount; - MemoryStream ms = Deflate(buffer, runLevel, runZlib); - Inflate(ms, buffer, runLevel, runZlib); + var ms = Deflate(buffer, _runLevel, _runZlib); + Inflate(ms, buffer, _runLevel, _runZlib); } - private void TryVariants(RunCompress test, byte[] buffer, int index) + private void TryVariants(RunCompress test, byte[] buffer, Random random, int index) { int worker = 0; while (worker <= 255) @@ -204,33 +190,34 @@ private void TryVariants(RunCompress test, byte[] buffer, int index) buffer[index] = (byte)worker; if (index < buffer.Length - 1) { - TryVariants(test, buffer, index + 1); + TryVariants(test, buffer, random, index + 1); } else { test(buffer); } - worker += runRandom.Next(256); + worker += random.Next(maxValue: 256); } } private void TryManyVariants(int level, bool zlib, RunCompress test, byte[] buffer) { - runLevel = level; - runZlib = zlib; - TryVariants(test, buffer, 0); + var random = new Random(RandomSeed); + _runLevel = level; + _runZlib = zlib; + TryVariants(test, buffer, random, 0); } // TODO: Fix this - //[Test] - //[Category("Base")] - //public void SmallBlocks() - //{ - // byte[] buffer = new byte[10]; - // Array.Clear(buffer, 0, buffer.Length); - // TryManyVariants(0, false, new RunCompress(DeflateAndInflate), buffer); - //} + [Test] + [Category("Base")] + [Explicit("Long-running")] + public void SmallBlocks() + { + var buffer = new byte[10]; + TryManyVariants(level: 0, zlib: false, DeflateAndInflate, buffer); + } /// /// Basic inflate/deflate test diff --git a/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs b/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs index 8a9f61d69..62be609fc 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs @@ -23,9 +23,7 @@ public void TestGZip() var ms = new MemoryStream(); var outStream = new GZipOutputStream(ms); - byte[] buf = new byte[100000]; - var rnd = new Random(); - rnd.NextBytes(buf); + var buf = Utils.GetDummyBytes(size: 100000); outStream.Write(buf, 0, buf.Length); outStream.Flush(); @@ -64,17 +62,15 @@ public void TestGZip() [Category("GZip")] public void DelayedHeaderWriteNoData() { - var ms = new MemoryStream(); - Assert.AreEqual(0, ms.Length); + using var ms = new MemoryStream(); + Assert.Zero(ms.Length); - using (GZipOutputStream outStream = new GZipOutputStream(ms)) + using (new GZipOutputStream(ms)) { - Assert.AreEqual(0, ms.Length); + Assert.Zero(ms.Length); } - byte[] data = ms.ToArray(); - - Assert.IsTrue(data.Length > 0); + Assert.NotZero(ms.ToArray().Length); } @@ -260,7 +256,7 @@ public void DoubleClose() s.Close(); memStream = new TrackedMemoryStream(); - using (GZipOutputStream no2 = new GZipOutputStream(memStream)) + using (new GZipOutputStream(memStream)) { s.Close(); } @@ -273,14 +269,7 @@ public void WriteAfterFinish() var s = new GZipOutputStream(memStream); s.Finish(); - try - { - s.WriteByte(7); - Assert.Fail("Write should fail"); - } - catch - { - } + Assert.Throws(() => s.WriteByte(value: 7), "Write should fail"); } [Test] @@ -290,14 +279,7 @@ public void WriteAfterClose() var s = new GZipOutputStream(memStream); s.Close(); - try - { - s.WriteByte(7); - Assert.Fail("Write should fail"); - } - catch - { - } + Assert.Throws(() => s.WriteByte(value: 7), "Write should fail"); } /// @@ -311,9 +293,7 @@ public void TrailingGarbage() var outStream = new GZipOutputStream(ms); // input buffer to be compressed - byte[] buf = new byte[100000]; - var rnd = new Random(); - rnd.NextBytes(buf); + var buf = Utils.GetDummyBytes(size: 100000, seed: 3); // compress input buffer outStream.Write(buf, 0, buf.Length); @@ -321,9 +301,7 @@ public void TrailingGarbage() outStream.Finish(); // generate random trailing garbage and add to the compressed stream - byte[] garbage = new byte[4096]; - rnd.NextBytes(garbage); - ms.Write(garbage, 0, garbage.Length); + Utils.WriteDummyData(ms, size: 4096, seed: 4); // rewind the concatenated stream ms.Seek(0, SeekOrigin.Begin); @@ -336,7 +314,7 @@ public void TrailingGarbage() int count = buf2.Length; while (true) { - int numRead = inStream.Read(buf2, currentIndex, count); + var numRead = inStream.Read(buf2, currentIndex, count); if (numRead <= 0) { break; @@ -346,7 +324,7 @@ public void TrailingGarbage() } /* ASSERT */ - Assert.AreEqual(0, count); + Assert.Zero(count); for (int i = 0; i < buf.Length; ++i) { Assert.AreEqual(buf2[i], buf[i]); @@ -365,9 +343,7 @@ public void FlushToUnderlyingStream() var ms = new MemoryStream(); var outStream = new GZipOutputStream(ms); - byte[] buf = new byte[100000]; - var rnd = new Random(); - rnd.NextBytes(buf); + byte[] buf = Utils.GetDummyBytes(size: 100000); outStream.Write(buf, 0, buf.Length); // Flush output stream but don't finish it yet @@ -414,48 +390,43 @@ public void SmallBufferDecompression() { var outputBufferSize = 100000; var inputBufferSize = outputBufferSize * 4; + var inputBuffer = Utils.GetDummyBytes(inputBufferSize, seed: 0); var outputBuffer = new byte[outputBufferSize]; - var inputBuffer = new byte[inputBufferSize]; - - using (var msGzip = new MemoryStream()) - { - using (var gzos = new GZipOutputStream(msGzip)) - { - gzos.IsStreamOwner = false; - var rnd = new Random(0); - rnd.NextBytes(inputBuffer); - gzos.Write(inputBuffer, 0, inputBuffer.Length); + using var msGzip = new MemoryStream(); + using (var gzos = new GZipOutputStream(msGzip)) + { + gzos.IsStreamOwner = false; - gzos.Flush(); - gzos.Finish(); - } + gzos.Write(inputBuffer, 0, inputBuffer.Length); + + gzos.Flush(); + gzos.Finish(); + } - msGzip.Seek(0, SeekOrigin.Begin); + msGzip.Seek(0, SeekOrigin.Begin); - using (var gzis = new GZipInputStream(msGzip)) - using (var msRaw = new MemoryStream()) - { + using (var gzis = new GZipInputStream(msGzip)) + using (var msRaw = new MemoryStream()) + { - int readOut; - while ((readOut = gzis.Read(outputBuffer, 0, outputBuffer.Length)) > 0) - { - msRaw.Write(outputBuffer, 0, readOut); - } + int readOut; + while ((readOut = gzis.Read(outputBuffer, 0, outputBuffer.Length)) > 0) + { + msRaw.Write(outputBuffer, 0, readOut); + } - var resultBuffer = msRaw.ToArray(); + var resultBuffer = msRaw.ToArray(); - for (var i = 0; i < resultBuffer.Length; i++) - { - Assert.AreEqual(inputBuffer[i], resultBuffer[i]); - } + for (var i = 0; i < resultBuffer.Length; i++) + { + Assert.AreEqual(inputBuffer[i], resultBuffer[i]); + } - } } - } /// @@ -467,18 +438,13 @@ public void SmallBufferDecompression() /// [Test] [Category("Zip")] - public void ShouldGracefullyHandleReadingANonReableStream() + public void ShouldGracefullyHandleReadingANonReadableStream() { MemoryStream ms = new SelfClosingStream(); using (var gzos = new GZipOutputStream(ms)) { gzos.IsStreamOwner = false; - - byte[] buf = new byte[100000]; - var rnd = new Random(); - rnd.NextBytes(buf); - - gzos.Write(buf, 0, buf.Length); + Utils.WriteDummyData(gzos, size: 100000); } ms.Seek(0, SeekOrigin.Begin); @@ -526,30 +492,26 @@ public void OriginalFilename() var content = "FileContents"; - using (var ms = new MemoryStream()) + using var ms = new MemoryStream(); + using (var outStream = new GZipOutputStream(ms) { IsStreamOwner = false }) { - using (var outStream = new GZipOutputStream(ms) { IsStreamOwner = false }) - { - outStream.FileName = "/path/to/file.ext"; + outStream.FileName = "/path/to/file.ext"; - var writeBuffer = Encoding.ASCII.GetBytes(content); - outStream.Write(writeBuffer, 0, writeBuffer.Length); - outStream.Flush(); - outStream.Finish(); - } + var writeBuffer = Encoding.ASCII.GetBytes(content); + outStream.Write(writeBuffer, 0, writeBuffer.Length); + outStream.Flush(); + outStream.Finish(); + } - ms.Seek(0, SeekOrigin.Begin); + ms.Seek(0, SeekOrigin.Begin); - using (var inStream = new GZipInputStream(ms)) - { - var readBuffer = new byte[content.Length]; - inStream.Read(readBuffer, 0, readBuffer.Length); - Assert.AreEqual(content, Encoding.ASCII.GetString(readBuffer)); - Assert.AreEqual("file.ext", inStream.GetFilename()); - } - + using (var inStream = new GZipInputStream(ms)) + { + var readBuffer = new byte[content.Length]; + inStream.Read(readBuffer, 0, readBuffer.Length); + Assert.AreEqual(content, Encoding.ASCII.GetString(readBuffer)); + Assert.AreEqual("file.ext", inStream.GetFilename()); } - } } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarArchiveTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarArchiveTests.cs index 374a9b1e3..d9e32194a 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarArchiveTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarArchiveTests.cs @@ -2,6 +2,7 @@ using System.Text; using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Tar; +using ICSharpCode.SharpZipLib.Tests.TestSupport; using static ICSharpCode.SharpZipLib.Tests.TestSupport.Utils; using NUnit.Framework; @@ -56,9 +57,9 @@ public void ExtractingContentsOnWindowsWithDisallowedPathsFails(string outputDir public void ExtractTarOK(string outputDir, string fileName, bool allowTraverse) { var fileContent = Encoding.UTF8.GetBytes("file content"); - using var tempDir = new TempDir(); + using var tempDir = GetTempDir(); - var tempPath = tempDir.Fullpath; + var tempPath = tempDir.FullName; var extractPath = Path.Combine(tempPath, outputDir); var expectedOutputFile = Path.Combine(extractPath, fileName); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs index 5cdd9404e..fae87a736 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Text; +using NUnit.Framework.Internal; namespace ICSharpCode.SharpZipLib.Tests.Tar { @@ -35,8 +36,8 @@ public void Setup() public void EmptyTar() { var ms = new MemoryStream(); - int recordSize = 0; - using (TarArchive tarOut = TarArchive.CreateOutputTarArchive(ms)) + int recordSize; + using (var tarOut = TarArchive.CreateOutputTarArchive(ms)) { recordSize = tarOut.RecordSize; } @@ -48,12 +49,12 @@ public void EmptyTar() ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); - using (TarArchive tarIn = TarArchive.CreateInputTarArchive(ms2, null)) + using (var tarIn = TarArchive.CreateInputTarArchive(ms2, nameEncoding: null)) { entryCount = 0; tarIn.ProgressMessageEvent += EntryCounter; tarIn.ListContents(); - Assert.AreEqual(0, entryCount, "Expected 0 tar entries"); + Assert.Zero(entryCount, "Expected 0 tar entries"); } } @@ -64,27 +65,24 @@ public void EmptyTar() [Category("Tar")] public void BlockFactorHandling() { - const int MinimumBlockFactor = 1; - const int MaximumBlockFactor = 64; - const int FillFactor = 2; + const int minimumBlockFactor = 1; + const int maximumBlockFactor = 64; + const int fillFactor = 2; - for (int factor = MinimumBlockFactor; factor < MaximumBlockFactor; ++factor) + for (var factor = minimumBlockFactor; factor < maximumBlockFactor; ++factor) { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms, factor, null)) + using (var tarOut = new TarOutputStream(ms, factor, nameEncoding: null)) { - TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); - entry.Size = (TarBuffer.BlockSize * factor * FillFactor); + var entry = TarEntry.CreateTarEntry("TestEntry"); + entry.Size = TarBuffer.BlockSize * factor * fillFactor; tarOut.PutNextEntry(entry); - byte[] buffer = new byte[TarBuffer.BlockSize]; - - var r = new Random(); - r.NextBytes(buffer); + var buffer = Utils.GetDummyBytes(TarBuffer.BlockSize); // Last block is a partial one - for (int i = 0; i < factor * FillFactor; ++i) + for (var i = 0; i < factor * fillFactor; ++i) { tarOut.Write(buffer, 0, buffer.Length); } @@ -94,7 +92,7 @@ public void BlockFactorHandling() Assert.IsNotNull(tarData, "Data written is null"); // Blocks = Header + Data Blocks + Zero block + Record trailer - int usedBlocks = 1 + (factor * FillFactor) + 2; + int usedBlocks = 1 + (factor * fillFactor) + 2; int totalBlocks = usedBlocks + (factor - 1); totalBlocks /= factor; totalBlocks *= factor; @@ -102,20 +100,18 @@ public void BlockFactorHandling() Assert.AreEqual(TarBuffer.BlockSize * totalBlocks, tarData.Length, "Tar file should contain {0} blocks in length", totalBlocks); - if (usedBlocks < totalBlocks) + if (usedBlocks >= totalBlocks) continue; + + // Start at first byte after header. + var byteIndex = TarBuffer.BlockSize * ((factor * fillFactor) + 1); + while (byteIndex < tarData.Length) { - // Start at first byte after header. - int byteIndex = TarBuffer.BlockSize * ((factor * FillFactor) + 1); - while (byteIndex < tarData.Length) - { - int blockNumber = byteIndex / TarBuffer.BlockSize; - int offset = blockNumber % TarBuffer.BlockSize; - Assert.AreEqual(0, tarData[byteIndex], - string.Format("Trailing block data should be null iteration {0} block {1} offset {2} index {3}", - factor, - blockNumber, offset, byteIndex)); - byteIndex += 1; - } + var blockNumber = byteIndex / TarBuffer.BlockSize; + var offset = blockNumber % TarBuffer.BlockSize; + Assert.AreEqual(0, tarData[byteIndex], + "Trailing block data should be null iteration {0} block {1} offset {2} index {3}", + factor, blockNumber, offset, byteIndex); + byteIndex += 1; } } } @@ -127,13 +123,13 @@ public void BlockFactorHandling() [Category("Tar")] public void TrailerContainsNulls() { - const int TestBlockFactor = 3; + const int testBlockFactor = 3; - for (int iteration = 0; iteration < TestBlockFactor * 2; ++iteration) + for (int iteration = 0; iteration < testBlockFactor * 2; ++iteration) { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms, TestBlockFactor, null)) + using (TarOutputStream tarOut = new TarOutputStream(ms, testBlockFactor, null)) { TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); if (iteration > 0) @@ -167,9 +163,9 @@ public void TrailerContainsNulls() // Blocks = Header + Data Blocks + Zero block + Record trailer int usedBlocks = 1 + iteration + 2; - int totalBlocks = usedBlocks + (TestBlockFactor - 1); - totalBlocks /= TestBlockFactor; - totalBlocks *= TestBlockFactor; + int totalBlocks = usedBlocks + (testBlockFactor - 1); + totalBlocks /= testBlockFactor; + totalBlocks *= testBlockFactor; Assert.AreEqual(TarBuffer.BlockSize * totalBlocks, tarData.Length, string.Format("Tar file should be {0} blocks in length", totalBlocks)); @@ -195,7 +191,7 @@ public void TrailerContainsNulls() private void TryLongName(string name) { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms, null)) + using (TarOutputStream tarOut = new TarOutputStream(ms, nameEncoding: null)) { DateTime modTime = DateTime.Now; @@ -207,7 +203,7 @@ private void TryLongName(string name) ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); - using (TarInputStream tarIn = new TarInputStream(ms2, null)) + using (TarInputStream tarIn = new TarInputStream(ms2, nameEncoding: null)) { TarEntry nextEntry = tarIn.GetNextEntry(); @@ -290,20 +286,15 @@ public void ExtendedHeaderLongName() var buffer = new byte[2560]; var truncated = Convert.FromBase64String(input64); Array.Copy(truncated, buffer, truncated.Length); - truncated = null; - - using (var ms = new MemoryStream(buffer)) - using (var tis = new TarInputStream(ms, null)) - { - var entry = tis.GetNextEntry(); - Assert.IsNotNull(entry, "Entry is null"); - Assert.IsNotNull(entry.Name, "Entry name is null"); - - Assert.AreEqual(expectedName.Length, entry.Name.Length, $"Entry name is truncated to {entry.Name.Length} bytes."); - - Assert.AreEqual(expectedName, entry.Name, "Entry name does not match expected value"); - } + using var ms = new MemoryStream(buffer); + using var tis = new TarInputStream(ms, nameEncoding: null); + var entry = tis.GetNextEntry(); + + Assert.IsNotNull(entry, "Entry is null"); + Assert.IsNotNull(entry.Name, "Entry name is null"); + Assert.AreEqual(expectedName.Length, entry.Name.Length, $"Entry name is truncated to {entry.Name.Length} bytes."); + Assert.AreEqual(expectedName, entry.Name, "Entry name does not match expected value"); } /// @@ -394,11 +385,9 @@ public void HeaderEquality() public void Checksum() { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms, null)) + using (var tarOut = new TarOutputStream(ms, nameEncoding: null)) { - DateTime modTime = DateTime.Now; - - TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); + var entry = TarEntry.CreateTarEntry("TestEntry"); entry.TarHeader.Mode = 12345; tarOut.PutNextEntry(entry); @@ -409,7 +398,7 @@ public void Checksum() ms2.Seek(0, SeekOrigin.Begin); TarEntry nextEntry; - using (TarInputStream tarIn = new TarInputStream(ms2, null)) + using (var tarIn = new TarInputStream(ms2, nameEncoding: null)) { nextEntry = tarIn.GetNextEntry(); Assert.IsTrue(nextEntry.TarHeader.IsChecksumValid, "Checksum should be valid"); @@ -421,20 +410,9 @@ public void Checksum() ms3.Write(new byte[] { 34 }, 0, 1); ms3.Seek(0, SeekOrigin.Begin); - using (TarInputStream tarIn = new TarInputStream(ms3, null)) + using (var tarIn = new TarInputStream(ms3, nameEncoding: null)) { - bool trapped = false; - - try - { - nextEntry = tarIn.GetNextEntry(); - } - catch (TarException) - { - trapped = true; - } - - Assert.IsTrue(trapped, "Checksum should be invalid"); + Assert.Throws(() => tarIn.GetNextEntry(), "Checksum should be invalid"); } } @@ -703,37 +681,35 @@ public void EndBlockHandling() long outCount, inCount; - using (var ms = new MemoryStream()) + using var ms = new MemoryStream(); + using (var tarOut = TarArchive.CreateOutputTarArchive(ms)) + using (var dummyFile = Utils.GetDummyFile(dummySize)) { - using (var tarOut = TarArchive.CreateOutputTarArchive(ms)) - using (var dummyFile = Utils.GetDummyFile(dummySize)) - { - tarOut.IsStreamOwner = false; - tarOut.WriteEntry(TarEntry.CreateEntryFromFile(dummyFile.Filename), false); - } + tarOut.IsStreamOwner = false; + tarOut.WriteEntry(TarEntry.CreateEntryFromFile(dummyFile), recurse: false); + } - outCount = ms.Position; - ms.Seek(0, SeekOrigin.Begin); + outCount = ms.Position; + ms.Seek(0, SeekOrigin.Begin); - using (var tarIn = TarArchive.CreateInputTarArchive(ms, null)) - using (var tempDir = new Utils.TempDir()) - { - tarIn.IsStreamOwner = false; - tarIn.ExtractContents(tempDir.Fullpath); + using (var tarIn = TarArchive.CreateInputTarArchive(ms, nameEncoding: null)) + using (var tempDir = Utils.GetTempDir()) + { + tarIn.IsStreamOwner = false; + tarIn.ExtractContents(tempDir); - foreach (var file in Directory.GetFiles(tempDir.Fullpath, "*", SearchOption.AllDirectories)) - { - Console.WriteLine($"Extracted \"{file}\""); - } + foreach (var file in Directory.GetFiles(tempDir, "*", SearchOption.AllDirectories)) + { + Console.WriteLine($"Extracted \"{file}\""); } + } - inCount = ms.Position; + inCount = ms.Position; - Console.WriteLine($"Output count: {outCount}"); - Console.WriteLine($"Input count: {inCount}"); + Console.WriteLine($"Output count: {outCount}"); + Console.WriteLine($"Input count: {inCount}"); - Assert.AreEqual(inCount, outCount, "Bytes read and bytes written should be equal"); - } + Assert.AreEqual(inCount, outCount, "Bytes read and bytes written should be equal"); } [Test] @@ -742,14 +718,14 @@ public void EndBlockHandling() [Explicit("Long Running")] public void WriteThroughput() { - const string EntryName = "LargeTarEntry"; + const string entryName = "LargeTarEntry"; PerformanceTesting.TestWrite(TestDataSize.Large, bs => { - var tos = new TarOutputStream(bs, null); + var tos = new TarOutputStream(bs, nameEncoding: null); tos.PutNextEntry(new TarEntry(new TarHeader() { - Name = EntryName, + Name = entryName, Size = (int)TestDataSize.Large, })); return tos; @@ -766,7 +742,7 @@ public void WriteThroughput() [Explicit("Long Running")] public void SingleLargeEntry() { - const string EntryName = "LargeTarEntry"; + const string entryName = "LargeTarEntry"; const TestDataSize dataSize = TestDataSize.Large; PerformanceTesting.TestReadWrite( @@ -776,7 +752,7 @@ public void SingleLargeEntry() var tis = new TarInputStream(bs, null); var entry = tis.GetNextEntry(); - Assert.AreEqual(EntryName, entry.Name); + Assert.AreEqual(entryName, entry.Name); return tis; }, output: bs => @@ -784,7 +760,7 @@ public void SingleLargeEntry() var tos = new TarOutputStream(bs, null); tos.PutNextEntry(new TarEntry(new TarHeader() { - Name = EntryName, + Name = entryName, Size = (int)dataSize, })); return tos; @@ -801,44 +777,40 @@ public void SingleLargeEntry() [Category("Tar")] public void ExtractingCorruptTarShouldntLeakFiles() { - using (var memoryStream = new MemoryStream()) + using var memoryStream = new MemoryStream(); + //Create a tar.gz in the output stream + using (var gzipStream = new GZipOutputStream(memoryStream)) { - //Create a tar.gz in the output stream - using (var gzipStream = new GZipOutputStream(memoryStream)) - { - gzipStream.IsStreamOwner = false; + gzipStream.IsStreamOwner = false; - using (var tarOut = TarArchive.CreateOutputTarArchive(gzipStream)) - using (var dummyFile = Utils.GetDummyFile(32000)) - { - tarOut.IsStreamOwner = false; - tarOut.WriteEntry(TarEntry.CreateEntryFromFile(dummyFile.Filename), false); - } + using (var tarOut = TarArchive.CreateOutputTarArchive(gzipStream)) + using (var dummyFile = Utils.GetDummyFile(size: 32000)) + { + tarOut.IsStreamOwner = false; + tarOut.WriteEntry(TarEntry.CreateEntryFromFile(dummyFile), recurse: false); } + } - // corrupt archive - make sure the file still has more than one block - memoryStream.SetLength(16000); - memoryStream.Seek(0, SeekOrigin.Begin); - - // try to extract - using (var gzipStream = new GZipInputStream(memoryStream)) - { - string tempDirName; - gzipStream.IsStreamOwner = false; + // corrupt archive - make sure the file still has more than one block + memoryStream.SetLength(16000); + memoryStream.Seek(0, SeekOrigin.Begin); - using (var tempDir = new Utils.TempDir()) - { - tempDirName = tempDir.Fullpath; - - using (var tarIn = TarArchive.CreateInputTarArchive(gzipStream, null)) - { - tarIn.IsStreamOwner = false; - Assert.Throws(() => tarIn.ExtractContents(tempDir.Fullpath)); - } - } + // try to extract + using (var gzipStream = new GZipInputStream(memoryStream)) + { + gzipStream.IsStreamOwner = false; - Assert.That(Directory.Exists(tempDirName), Is.False, "Temporary folder should have been removed"); + using var tempDir = Utils.GetTempDir(); + using (var tarIn = TarArchive.CreateInputTarArchive(gzipStream, nameEncoding: null)) + { + tarIn.IsStreamOwner = false; + Assert.Throws(() => tarIn.ExtractContents(tempDir)); } + + // Try to remove the output directory to check if any file handles are still being held + Assert.DoesNotThrow(() => tempDir.Delete()); + + Assert.That(tempDir.Exists, Is.False, "Temporary folder should have been removed"); } } [TestCase(10, "utf-8")] diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs index 3d67a9c70..e1d7a1fb0 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace ICSharpCode.SharpZipLib.Tests.TestSupport { @@ -6,36 +7,20 @@ public static class StringTesting { static StringTesting() { - AddLanguage("Chinese", "測試.txt", "big5"); - AddLanguage("Greek", "Ϗΰ.txt", "windows-1253"); - AddLanguage("Nordic", "Åæ.txt", "windows-1252"); - AddLanguage("Arabic", "ڀڅ.txt", "windows-1256"); - AddLanguage("Russian", "Прйвёт.txt", "windows-1251"); - } - - private static void AddLanguage(string language, string filename, string encoding) - { - languages.Add(language); - filenames.Add(filename); - encodings.Add(encoding); - entries++; + TestSamples = new [] + { + ("Chinese", "測試.txt", "big5"), + ("Greek", "Ϗΰ.txt", "windows-1253"), + ("Nordic", "Åæ.txt", "windows-1252"), + ("Arabic", "ڀڅ.txt", "windows-1256"), + ("Russian", "Прйвёт.txt", "windows-1251"), + }; } - private static int entries = 0; - private static List languages = new List(); - private static List filenames = new List(); - private static List encodings = new List(); + public static (string language, string filename, string encoding)[] TestSamples { get; } - public static IEnumerable Languages => filenames.AsReadOnly(); - public static IEnumerable Filenames => filenames.AsReadOnly(); - public static IEnumerable Encodings => filenames.AsReadOnly(); - - public static IEnumerable<(string language, string filename, string encoding)> GetTestSamples() - { - for (int i = 0; i < entries; i++) - { - yield return (languages[i], filenames[i], encodings[i]); - } - } + public static IEnumerable Languages => TestSamples.Select(s => s.language); + public static IEnumerable Filenames => TestSamples.Select(s => s.filename); + public static IEnumerable Encodings => TestSamples.Select(s => s.encoding); } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs index 33d6e3e9b..179202b44 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using System; using System.IO; -using System.Text; +using System.Linq; namespace ICSharpCode.SharpZipLib.Tests.TestSupport { @@ -10,9 +10,7 @@ namespace ICSharpCode.SharpZipLib.Tests.TestSupport /// public static class Utils { - public static int DummyContentLength = 16; - - private static Random random = new Random(); + internal const int DefaultSeed = 5; /// /// Returns the system root for the current platform (usually c:\ for windows and / for others) @@ -40,125 +38,200 @@ private static void Compare(byte[] a, byte[] b) } } - public static void WriteDummyData(string fileName, int size = -1) + /// + /// Write pseudo-random data to , + /// creating it if it does not exist or truncating it otherwise + /// + /// + /// + /// + public static void WriteDummyData(string fileName, int size, int seed = DefaultSeed) { - using(var fs = File.OpenWrite(fileName)) - { - WriteDummyData(fs, size); - } + using var fs = File.Create(fileName); + WriteDummyData(fs, size, seed); } - public static void WriteDummyData(Stream stream, int size = -1) + /// + /// Write pseudo-random data to + /// + /// + /// + /// + public static void WriteDummyData(Stream stream, int size, int seed = DefaultSeed) { - var bytes = (size < 0) - ? Encoding.ASCII.GetBytes(DateTime.UtcNow.Ticks.ToString("x16")) - : new byte[size]; - - if(size > 0) - { - random.NextBytes(bytes); - } - - stream.Write(bytes, 0, bytes.Length); + var bytes = GetDummyBytes(size, seed); + stream.Write(bytes, offset: 0, bytes.Length); + } + + /// + /// Creates a buffer of pseudo-random bytes + /// + /// + /// + /// + public static byte[] GetDummyBytes(int size, int seed = DefaultSeed) + { + var random = new Random(seed); + var bytes = new byte[size]; + random.NextBytes(bytes); + return bytes; } - public static TempFile GetDummyFile(int size = -1) + /// + /// Returns a file reference with bytes of dummy data written to it + /// + /// + /// + public static TempFile GetDummyFile(int size = 16) { var tempFile = new TempFile(); - WriteDummyData(tempFile.Filename, size); + using var fs = tempFile.Create(); + WriteDummyData(fs, size); return tempFile; } + /// + /// Returns a randomized file/directory name (without any path) using a generated GUID + /// + /// public static string GetDummyFileName() - => $"{random.Next():x8}{random.Next():x8}{random.Next():x8}"; - - public class TempFile : IDisposable - { - public string Filename { get; internal set; } - - public TempFile() - { - Filename = Path.GetTempFileName(); - } + => string.Concat(Guid.NewGuid().ToByteArray().Select(b => $"{b:x2}")); - #region IDisposable Support - - private bool disposed = false; // To detect redundant calls - - protected virtual void Dispose(bool disposing) - { - if (!disposed) - { - if (disposing && File.Exists(Filename)) - { - try - { - File.Delete(Filename); - } - catch { } - } - - disposed = true; - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion IDisposable Support - } - - public class TempDir : IDisposable - { - public string Fullpath { get; internal set; } - - public TempDir() - { - Fullpath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(Fullpath); - } - - #region IDisposable Support - - private bool disposed = false; // To detect redundant calls + /// + /// Returns a reference to a temporary directory that deletes it's contents when disposed + /// + /// + public static TempDir GetTempDir() => new TempDir(); - protected virtual void Dispose(bool disposing) - { - if (!disposed) - { - if (disposing && Directory.Exists(Fullpath)) - { - try - { - Directory.Delete(Fullpath, true); - } - catch { } - } - - disposed = true; - } - } + /// + /// Returns a reference to a temporary file that deletes it's referred file when disposed + /// + /// + public static TempFile GetTempFile() => new TempFile(); + } + + public class TempFile : FileSystemInfo, IDisposable + { + private FileInfo _fileInfo; - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } + public override string Name => _fileInfo.Name; + public override bool Exists => _fileInfo.Exists; + public string DirectoryName => _fileInfo.DirectoryName; - internal string CreateDummyFile(int size = -1) - => CreateDummyFile(GetDummyFileName(), size); + public override string FullName => _fileInfo.FullName; - internal string CreateDummyFile(string name, int size = -1) - { - var fileName = Path.Combine(Fullpath, name); - WriteDummyData(fileName, size); - return fileName; - } + public byte[] ReadAllBytes() => File.ReadAllBytes(_fileInfo.FullName); - #endregion IDisposable Support - } + public static implicit operator string(TempFile tf) => tf._fileInfo.FullName; + + public override void Delete() + { + if(!Exists) return; + _fileInfo.Delete(); + } + + public FileStream Create() => _fileInfo.Create(); + + public static TempFile WithDummyData(int size, string dirPath = null, string filename = null, int seed = Utils.DefaultSeed) + { + var tempFile = new TempFile(dirPath, filename); + Utils.WriteDummyData(tempFile.FullName, size, seed); + return tempFile; + } + + internal TempFile(string dirPath = null, string filename = null) + { + dirPath ??= Path.GetTempPath(); + filename ??= Utils.GetDummyFileName(); + _fileInfo = new FileInfo(Path.Combine(dirPath, filename)); + } + + #region IDisposable Support + + private bool _disposed; // To detect redundant calls + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + if (disposing) + { + try + { + Delete(); + } + catch + { + // ignored + } + } + + _disposed = true; + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + #endregion IDisposable Support + + } + public class TempDir : FileSystemInfo, IDisposable + { + public override string Name => Path.GetFileName(FullName); + public override bool Exists => Directory.Exists(FullName); + + public static implicit operator string(TempDir td) => td.FullName; + + public override void Delete() + { + if(!Exists) return; + Directory.Delete(FullPath, recursive: true); + } + + public TempDir() + { + FullPath = Path.Combine(Path.GetTempPath(), Utils.GetDummyFileName()); + Directory.CreateDirectory(FullPath); + } + + public TempFile CreateDummyFile(int size = 16, int seed = Utils.DefaultSeed) + => CreateDummyFile(null, size); + + public TempFile CreateDummyFile(string name, int size = 16, int seed = Utils.DefaultSeed) + => TempFile.WithDummyData(size, FullPath, name, seed); + + public TempFile GetFile(string fileName) => new TempFile(FullPath, fileName); + + #region IDisposable Support + + private bool _disposed; // To detect redundant calls + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + if (disposing) + { + try + { + Delete(); + } + catch + { + // ignored + } + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion IDisposable Support + } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs index fce26c2c4..f1c9863da 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs @@ -103,12 +103,12 @@ public void ExtractEmptyDirectories() [Category("CreatesTempFile")] public void CreateEmptyDirectories(string password) { - using (var tempFilePath = new Utils.TempDir()) + using (var tempFilePath = Utils.GetTempDir()) { - string name = Path.Combine(tempFilePath.Fullpath, "x.zip"); + string name = Path.Combine(tempFilePath.FullName, "x.zip"); // Create empty test folders (The folder that we'll zip, and the test sub folder). - string archiveRootDir = Path.Combine(tempFilePath.Fullpath, ZipTempDir); + string archiveRootDir = Path.Combine(tempFilePath.FullName, ZipTempDir); string targetDir = Path.Combine(archiveRootDir, "floyd"); Directory.CreateDirectory(targetDir); @@ -118,7 +118,7 @@ public void CreateEmptyDirectories(string password) CreateEmptyDirectories = true, Password = password, }; - fastZip.CreateZip(name, archiveRootDir, true, null); + fastZip.CreateZip(name, archiveRootDir, recurse: true, fileFilter: null); // Test that the archive contains the empty folder entry using (var zipFile = new ZipFile(name)) @@ -128,7 +128,7 @@ public void CreateEmptyDirectories(string password) var folderEntry = zipFile.GetEntry("floyd/"); Assert.That(folderEntry.IsDirectory, Is.True, "The entry must be a folder"); - Assert.IsTrue(zipFile.TestArchive(true)); + Assert.IsTrue(zipFile.TestArchive(testData: true)); } } } @@ -138,25 +138,24 @@ public void CreateEmptyDirectories(string password) [Category("CreatesTempFile")] public void ContentEqualAfterAfterArchived([Values(0, 1, 64)]int contentSize) { - using(var sourceDir = new Utils.TempDir()) - using(var targetDir = new Utils.TempDir()) - using(var zipFile = Utils.GetDummyFile(0)) - { - var sourceFile = sourceDir.CreateDummyFile(contentSize); - var sourceContent = File.ReadAllBytes(sourceFile); - new FastZip().CreateZip(zipFile.Filename, sourceDir.Fullpath, true, null); - - Assert.DoesNotThrow(() => - { - new FastZip().ExtractZip(zipFile.Filename, targetDir.Fullpath, null); - }, "Exception during extraction of test archive"); + using var sourceDir = Utils.GetTempDir(); + using var targetDir = Utils.GetTempDir(); + using var zipFile = Utils.GetTempFile(); + + var sourceFile = sourceDir.CreateDummyFile(contentSize); + var sourceContent = sourceFile.ReadAllBytes(); + new FastZip().CreateZip(zipFile.FullName, sourceDir.FullName, recurse: true, fileFilter: null); + + Assert.DoesNotThrow(() => + { + new FastZip().ExtractZip(zipFile, targetDir, fileFilter: null); + }, "Exception during extraction of test archive"); - var targetFile = Path.Combine(targetDir.Fullpath, Path.GetFileName(sourceFile)); - var targetContent = File.ReadAllBytes(targetFile); + var targetFile = Path.Combine(targetDir, Path.GetFileName(sourceFile)); + var targetContent = File.ReadAllBytes(targetFile); - Assert.AreEqual(sourceContent.Length, targetContent.Length, "Extracted file size does not match source file size"); - Assert.AreEqual(sourceContent, targetContent, "Extracted content does not match source content"); - } + Assert.AreEqual(sourceContent.Length, targetContent.Length, "Extracted file size does not match source file size"); + Assert.AreEqual(sourceContent, targetContent, "Extracted content does not match source content"); } [Test] @@ -230,64 +229,55 @@ public void CreateExceptions() { Assert.Throws(() => { - using (var tempDir = new Utils.TempDir()) - { - var fastZip = new FastZip(); - var badPath = Path.Combine(Path.GetTempPath(), Utils.GetDummyFileName()); - var addFile = Path.Combine(tempDir.Fullpath, "test.zip"); - fastZip.CreateZip(addFile, badPath, false, null); - } + using var tempDir = Utils.GetTempDir(); + var fastZip = new FastZip(); + var badPath = Path.Combine(Path.GetTempPath(), Utils.GetDummyFileName()); + var addFile = tempDir.GetFile("test.zip"); + fastZip.CreateZip(addFile, badPath, recurse: false, fileFilter: null); }); } #region String testing helper - private void TestFileNames(params string[] names) - => TestFileNames((IEnumerable)names); - - private void TestFileNames(IEnumerable names) + private void TestFileNames(IReadOnlyList names) { var zippy = new FastZip(); - using (var tempDir = new Utils.TempDir()) - using (var tempZip = new Utils.TempFile()) + using var tempDir = Utils.GetTempDir(); + using var tempZip = Utils.GetTempFile(); + int nameCount = 0; + foreach (var name in names) { - int nameCount = 0; - foreach (var name in names) - { - tempDir.CreateDummyFile(name); - nameCount++; - } + tempDir.CreateDummyFile(name); + nameCount++; + } - zippy.CreateZip(tempZip.Filename, tempDir.Fullpath, true, null); + zippy.CreateZip(tempZip, tempDir, recurse: true, fileFilter: null); - using (ZipFile z = new ZipFile(tempZip.Filename)) - { - Assert.AreEqual(nameCount, z.Count); - foreach (var name in names) - { - var index = z.FindEntry(name, true); + using var zf = new ZipFile(tempZip); + Assert.AreEqual(nameCount, zf.Count); + foreach (var name in names) + { + var index = zf.FindEntry(name, ignoreCase: true); - Assert.AreNotEqual(-1, index, "Zip entry \"{0}\" not found", name); + Assert.AreNotEqual(expected: -1, index, "Zip entry \"{0}\" not found", name); - var entry = z[index]; + var entry = zf[index]; - if (ZipStrings.UseUnicode) - { - Assert.IsTrue(entry.IsUnicodeText, "Zip entry #{0} not marked as unicode", index); - } - else - { - Assert.IsFalse(entry.IsUnicodeText, "Zip entry #{0} marked as unicode", index); - } + if (ZipStrings.UseUnicode) + { + Assert.IsTrue(entry.IsUnicodeText, "Zip entry #{0} not marked as unicode", index); + } + else + { + Assert.IsFalse(entry.IsUnicodeText, "Zip entry #{0} marked as unicode", index); + } - Assert.AreEqual(name, entry.Name); + Assert.AreEqual(name, entry.Name); - var nameBytes = string.Join(" ", Encoding.BigEndianUnicode.GetBytes(entry.Name).Select(b => b.ToString("x2"))); + var nameBytes = string.Join(" ", Encoding.BigEndianUnicode.GetBytes(entry.Name).Select(b => b.ToString("x2"))); - Console.WriteLine($" - Zip entry: {entry.Name} ({nameBytes})"); - } - } + Console.WriteLine($" - Zip entry: {entry.Name} ({nameBytes})"); } } @@ -301,7 +291,7 @@ public void UnicodeText() var preCp = ZipStrings.CodePage; try { - TestFileNames(StringTesting.Filenames); + TestFileNames(StringTesting.Filenames.ToArray()); } finally { @@ -319,7 +309,7 @@ public void NonUnicodeText() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - foreach ((string language, string filename, string encoding) in StringTesting.GetTestSamples()) + foreach (var (language, filename, encoding) in StringTesting.TestSamples) { Console.WriteLine($"{language} filename \"{filename}\" using \"{encoding}\":"); @@ -337,7 +327,7 @@ public void NonUnicodeText() } ZipStrings.CodePage = Encoding.GetEncoding(encoding).CodePage; - TestFileNames(filename); + TestFileNames(new []{filename}); } } finally @@ -659,32 +649,27 @@ public void CreateZipShouldLeaveOutputStreamOpenIfRequested(bool leaveOpen) { const string tempFileName = "a(2).dat"; - using (var tempFolder = new Utils.TempDir()) - { - // Create test input file - string addFile = Path.Combine(tempFolder.Fullpath, tempFileName); - MakeTempFile(addFile, 16); + using var tempFolder = Utils.GetTempDir(); + // Create test input file + tempFolder.CreateDummyFile(tempFileName, size: 16); - // Create the zip with fast zip - var target = new TrackedMemoryStream(); - var fastZip = new FastZip(); + // Create the zip with fast zip + var target = new TrackedMemoryStream(); + var fastZip = new FastZip(); - fastZip.CreateZip(target, tempFolder.Fullpath, false, @"a\(2\)\.dat", null, leaveOpen: leaveOpen); + fastZip.CreateZip(target, tempFolder, recurse: false, @"a\(2\)\.dat", directoryFilter: null, leaveOpen); - // Check that the output stream was disposed (or not) as expected - Assert.That(target.IsDisposed, Is.Not.EqualTo(leaveOpen), "IsDisposed should be the opposite of leaveOpen"); + // Check that the output stream was disposed (or not) as expected + Assert.That(target.IsDisposed, Is.Not.EqualTo(leaveOpen), "IsDisposed should be the opposite of leaveOpen"); - // Check that the file contents are correct in both cases - var archive = new MemoryStream(target.ToArray()); - using (ZipFile zf = new ZipFile(archive)) - { - Assert.AreEqual(1, zf.Count); - ZipEntry entry = zf[0]; - Assert.AreEqual(tempFileName, entry.Name); - Assert.AreEqual(16, entry.Size); - Assert.IsTrue(zf.TestArchive(true)); - } - } + // Check that the file contents are correct in both cases + var archive = new MemoryStream(target.ToArray()); + using var zf = new ZipFile(archive); + Assert.AreEqual(expected: 1, zf.Count); + var entry = zf[0]; + Assert.AreEqual(tempFileName, entry.Name); + Assert.AreEqual(expected: 16, entry.Size); + Assert.IsTrue(zf.TestArchive(testData: true)); } [Category("Zip")] @@ -748,15 +733,13 @@ public void ExtractZipShouldSetTimeOnFilesFromConstructorTimeSetting(TimeSetting } var fastZip = new FastZip(timeSetting); - using (var extractDir = new Utils.TempDir()) - { - fastZip.ExtractZip(archiveStream, extractDir.Fullpath, FastZip.Overwrite.Always, - _ => true, "", "", true, true, false); - var fi = new FileInfo(Path.Combine(extractDir.Fullpath, SingleEntryFileName)); - var actualTime = FileTimeFromTimeSetting(fi, timeSetting); - // Assert that the time is within +/- 2s of the target time to allow for timing/rounding discrepancies - Assert.LessOrEqual(Math.Abs((targetTime - actualTime).TotalSeconds), 2); - } + using var extractDir = Utils.GetTempDir(); + fastZip.ExtractZip(archiveStream, extractDir.FullName, FastZip.Overwrite.Always, + _ => true, "", "", restoreDateTime: true, isStreamOwner: true, allowParentTraversal: false); + var fi = new FileInfo(Path.Combine(extractDir.FullName, SingleEntryFileName)); + var actualTime = FileTimeFromTimeSetting(fi, timeSetting); + // Assert that the time is within +/- 2s of the target time to allow for timing/rounding discrepancies + Assert.LessOrEqual(Math.Abs((targetTime - actualTime).TotalSeconds), 2); } [Category("Zip")] @@ -770,15 +753,13 @@ public void ExtractZipShouldSetTimeOnFilesFromConstructorDateTime(DateTimeKind d // Extract the archive with a fixed time override var targetTime = ExpectedFixedTime(dtk); var fastZip = new FastZip(targetTime); - using (var extractDir = new Utils.TempDir()) - { - fastZip.ExtractZip(target, extractDir.Fullpath, FastZip.Overwrite.Always, - _ => true, "", "", true, true, false); - var fi = new FileInfo(Path.Combine(extractDir.Fullpath, SingleEntryFileName)); - var fileTime = FileTimeFromTimeSetting(fi, TimeSetting.Fixed); - if (fileTime.Kind != dtk) fileTime = fileTime.ToUniversalTime(); - Assert.AreEqual(targetTime, fileTime); - } + using var extractDir = Utils.GetTempDir(); + fastZip.ExtractZip(target, extractDir.FullName, FastZip.Overwrite.Always, + _ => true, "", "", restoreDateTime: true, isStreamOwner: true, allowParentTraversal: false); + var fi = new FileInfo(Path.Combine(extractDir.FullName, SingleEntryFileName)); + var fileTime = FileTimeFromTimeSetting(fi, TimeSetting.Fixed); + if (fileTime.Kind != dtk) fileTime = fileTime.ToUniversalTime(); + Assert.AreEqual(targetTime, fileTime); } [Category("Zip")] @@ -792,13 +773,11 @@ public void ExtractZipShouldSetTimeOnFilesWithEmptyConstructor(DateTimeKind dtk) // Extract the archive with an empty constructor var fastZip = new FastZip(); - using (var extractDir = new Utils.TempDir()) - { - fastZip.ExtractZip(target, extractDir.Fullpath, FastZip.Overwrite.Always, - _ => true, "", "", true, true, false); - var fi = new FileInfo(Path.Combine(extractDir.Fullpath, SingleEntryFileName)); - Assert.AreEqual(targetTime, FileTimeFromTimeSetting(fi, TimeSetting.Fixed)); - } + using var extractDir = Utils.GetTempDir(); + fastZip.ExtractZip(target, extractDir.FullName, FastZip.Overwrite.Always, + _ => true, "", "", restoreDateTime: true, isStreamOwner: true, allowParentTraversal: false); + var fi = new FileInfo(Path.Combine(extractDir.FullName, SingleEntryFileName)); + Assert.AreEqual(targetTime, FileTimeFromTimeSetting(fi, TimeSetting.Fixed)); } private static bool IsLastAccessTime(TimeSetting ts) @@ -851,17 +830,15 @@ private static TrackedMemoryStream CreateFastZipTestArchiveWithAnEntry(FastZip f { var target = new TrackedMemoryStream(); - using (var tempFolder = new Utils.TempDir()) - { + using var tempFolder = Utils.GetTempDir(); + // Create test input file + var addFile = Path.Combine(tempFolder.FullName, SingleEntryFileName); + MakeTempFile(addFile, 16); + var fi = new FileInfo(addFile); + alterFile?.Invoke(fi); - // Create test input file - var addFile = Path.Combine(tempFolder.Fullpath, SingleEntryFileName); - MakeTempFile(addFile, 16); - var fi = new FileInfo(addFile); - alterFile?.Invoke(fi); - - fastZip.CreateZip(target, tempFolder.Fullpath, false, SingleEntryFileName, null, leaveOpen: true); - } + fastZip.CreateZip(target, tempFolder.FullName, recurse: false, + SingleEntryFileName, directoryFilter: null, leaveOpen: true); return target; } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs index 7a336592a..3e8b9a9ee 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs @@ -44,9 +44,9 @@ public void ParameterHandling() ms.Seek(0, SeekOrigin.Begin); var inStream = new ZipInputStream(ms); - ZipEntry e = inStream.GetNextEntry(); + inStream.GetNextEntry(); - MustFailRead(inStream, null, 0, 0); + MustFailRead(inStream, buffer: null, 0, 0); MustFailRead(inStream, buffer, -1, 1); MustFailRead(inStream, buffer, 0, 11); MustFailRead(inStream, buffer, 7, 5); @@ -114,14 +114,13 @@ public void ReadAndWriteZip64NonSeekable() msw.Position = 0; - using (ZipInputStream zis = new ZipInputStream(msw)) + using (var zis = new ZipInputStream(msw)) { while (zis.GetNextEntry() != null) { - int len = 0; - int bufferSize = 1024; - byte[] buffer = new byte[bufferSize]; - while ((len = zis.Read(buffer, 0, bufferSize)) > 0) + const int bufferSize = 1024; + var buffer = new byte[bufferSize]; + while (zis.Read(buffer, 0, bufferSize) > 0) { // Reading the data is enough } @@ -241,46 +240,40 @@ public void WriteZipStreamWithNoCompression([Values(0, 1, 256)] int contentLengt { var buffer = new byte[255]; - using (var dummyZip = Utils.GetDummyFile(0)) - using (var inputFile = Utils.GetDummyFile(contentLength)) - { - // Filename is manually cleaned here to prevent this test from failing while ZipEntry doesn't automatically clean it - var inputFileName = ZipEntry.CleanName(inputFile.Filename); + using var dummyZip = Utils.GetTempFile(); + using var inputFile = Utils.GetDummyFile(contentLength); + // Filename is manually cleaned here to prevent this test from failing while ZipEntry doesn't automatically clean it + var inputFileName = ZipEntry.CleanName(inputFile); - using (var zipFileStream = File.OpenWrite(dummyZip.Filename)) - using (var zipOutputStream = new ZipOutputStream(zipFileStream)) - using (var inputFileStream = File.OpenRead(inputFile.Filename)) + using (var zipFileStream = File.OpenWrite(dummyZip)) + using (var zipOutputStream = new ZipOutputStream(zipFileStream)) + using (var inputFileStream = File.OpenRead(inputFile)) + { + zipOutputStream.PutNextEntry(new ZipEntry(inputFileName) { - zipOutputStream.PutNextEntry(new ZipEntry(inputFileName) - { - CompressionMethod = CompressionMethod.Stored, - }); - - StreamUtils.Copy(inputFileStream, zipOutputStream, buffer); - } + CompressionMethod = CompressionMethod.Stored, + }); - using (var zf = new ZipFile(dummyZip.Filename)) - { - var inputBytes = File.ReadAllBytes(inputFile.Filename); + StreamUtils.Copy(inputFileStream, zipOutputStream, buffer); + } - var entry = zf.GetEntry(inputFileName); - Assert.IsNotNull(entry, "No entry matching source file \"{0}\" found in archive, found \"{1}\"", inputFileName, zf[0].Name); + using (var zf = new ZipFile(dummyZip)) + { + var inputBytes = File.ReadAllBytes(inputFile); - Assert.DoesNotThrow(() => - { - using (var entryStream = zf.GetInputStream(entry)) - { - var outputBytes = new byte[entryStream.Length]; - entryStream.Read(outputBytes, 0, outputBytes.Length); + var entry = zf.GetEntry(inputFileName); + Assert.IsNotNull(entry, "No entry matching source file \"{0}\" found in archive, found \"{1}\"", inputFileName, zf[0].Name); - Assert.AreEqual(inputBytes, outputBytes, "Archive content does not match the source content"); - } - }, "Failed to locate entry stream in archive"); + Assert.DoesNotThrow(() => + { + using var entryStream = zf.GetInputStream(entry); + var outputBytes = new byte[entryStream.Length]; + entryStream.Read(outputBytes, 0, outputBytes.Length); - Assert.IsTrue(zf.TestArchive(testData: true), "Archive did not pass TestArchive"); - } + Assert.AreEqual(inputBytes, outputBytes, "Archive content does not match the source content"); + }, "Failed to locate entry stream in archive"); - + Assert.IsTrue(zf.TestArchive(testData: true), "Archive did not pass TestArchive"); } } @@ -288,26 +281,25 @@ public void WriteZipStreamWithNoCompression([Values(0, 1, 256)] int contentLengt [Category("Zip")] public void ZipEntryFileNameAutoClean() { - using (var dummyZip = Utils.GetDummyFile(0)) - using (var inputFile = Utils.GetDummyFile()) { - using (var zipFileStream = File.OpenWrite(dummyZip.Filename)) - using (var zipOutputStream = new ZipOutputStream(zipFileStream)) - using (var inputFileStream = File.OpenRead(inputFile.Filename)) + using var dummyZip = Utils.GetDummyFile(0); + using var inputFile = Utils.GetDummyFile(); + using (var zipFileStream = File.OpenWrite(dummyZip)) + using (var zipOutputStream = new ZipOutputStream(zipFileStream)) + using (var inputFileStream = File.OpenRead(inputFile)) + { + // New ZipEntry created with a full file name path as it's name + zipOutputStream.PutNextEntry(new ZipEntry(inputFile) { - // New ZipEntry created with a full file name path as it's name - zipOutputStream.PutNextEntry(new ZipEntry(inputFile.Filename) - { - CompressionMethod = CompressionMethod.Stored, - }); + CompressionMethod = CompressionMethod.Stored, + }); - inputFileStream.CopyTo(zipOutputStream); - } + inputFileStream.CopyTo(zipOutputStream); + } - using (var zf = new ZipFile(dummyZip.Filename)) - { - // The ZipEntry name should have been automatically cleaned - Assert.AreEqual(ZipEntry.CleanName(inputFile.Filename), zf[0].Name); - } + using (var zf = new ZipFile(dummyZip)) + { + // The ZipEntry name should have been automatically cleaned + Assert.AreEqual(ZipEntry.CleanName(inputFile), zf[0].Name); } } @@ -424,7 +416,7 @@ public void WriteThroughput() [Explicit("Long Running")] public void SingleLargeEntry() { - const string EntryName = "CantSeek"; + const string entryName = "CantSeek"; PerformanceTesting.TestReadWrite( size: TestDataSize.Large, @@ -433,14 +425,14 @@ public void SingleLargeEntry() var zis = new ZipInputStream(bs); var entry = zis.GetNextEntry(); - Assert.AreEqual(EntryName, entry.Name); + Assert.AreEqual(entryName, entry.Name); Assert.IsTrue((entry.Flags & (int)GeneralBitFlags.Descriptor) != 0); return zis; }, output: bs => { var zos = new ZipOutputStream(bs); - zos.PutNextEntry(new ZipEntry(EntryName)); + zos.PutNextEntry(new ZipEntry(entryName)); return zos; } ); @@ -458,20 +450,18 @@ public void SingleLargeEntry() [Category("Zip")] public void ShouldReadBZip2EntryButNotDecompress() { - var fileBytes = System.Convert.FromBase64String(BZip2CompressedZip); + var fileBytes = Convert.FromBase64String(BZip2CompressedZip); - using (var input = new MemoryStream(fileBytes, false)) - { - var zis = new ZipInputStream(input); - var entry = zis.GetNextEntry(); + using var input = new MemoryStream(fileBytes, writable: false); + var zis = new ZipInputStream(input); + var entry = zis.GetNextEntry(); - Assert.That(entry.Name, Is.EqualTo("a.dat"), "Should be able to get entry name"); - Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.BZip2), "Entry should be BZip2 compressed"); - Assert.That(zis.CanDecompressEntry, Is.False, "Should not be able to decompress BZip2 entry"); + Assert.That(entry.Name, Is.EqualTo("a.dat"), "Should be able to get entry name"); + Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.BZip2), "Entry should be BZip2 compressed"); + Assert.That(zis.CanDecompressEntry, Is.False, "Should not be able to decompress BZip2 entry"); - var buffer = new byte[1]; - Assert.Throws(() => zis.Read(buffer, 0, 1), "Trying to read the stream should throw"); - } + var buffer = new byte[1]; + Assert.Throws(() => zis.Read(buffer, 0, 1), "Trying to read the stream should throw"); } /// @@ -510,50 +500,44 @@ public void ShouldBeAbleToReadEntriesWithInvalidFileNames() [Category("Zip")] public void AddingAnAESEntryWithNoPasswordShouldThrow() { - using (var memoryStream = new MemoryStream()) - { - using (var outStream = new ZipOutputStream(memoryStream)) - { - var newEntry = new ZipEntry("test") { AESKeySize = 256 }; + using var memoryStream = new MemoryStream(); + using var outStream = new ZipOutputStream(memoryStream); + var newEntry = new ZipEntry("test") { AESKeySize = 256 }; - Assert.Throws(() => outStream.PutNextEntry(newEntry)); - } - } + Assert.Throws(() => outStream.PutNextEntry(newEntry)); } [Test] [Category("Zip")] public void ShouldThrowDescriptiveExceptionOnUncompressedDescriptorEntry() { - using (var ms = new MemoryStreamWithoutSeek()) + using var ms = new MemoryStreamWithoutSeek(); + using (var zos = new ZipOutputStream(ms)) { - using (var zos = new ZipOutputStream(ms)) - { - zos.IsStreamOwner = false; - var entry = new ZipEntry("testentry"); - entry.CompressionMethod = CompressionMethod.Stored; - entry.Flags |= (int)GeneralBitFlags.Descriptor; - zos.PutNextEntry(entry); - zos.Write(new byte[1], 0, 1); - zos.CloseEntry(); - } + zos.IsStreamOwner = false; + var entry = new ZipEntry("testentry"); + entry.CompressionMethod = CompressionMethod.Stored; + entry.Flags |= (int)GeneralBitFlags.Descriptor; + zos.PutNextEntry(entry); + zos.Write(new byte[1], 0, 1); + zos.CloseEntry(); + } - // Patch the Compression Method, since ZipOutputStream automatically changes it to Deflate when descriptors are used - ms.Seek(8, SeekOrigin.Begin); - ms.WriteByte((byte)CompressionMethod.Stored); - ms.Seek(0, SeekOrigin.Begin); + // Patch the Compression Method, since ZipOutputStream automatically changes it to Deflate when descriptors are used + ms.Seek(8, SeekOrigin.Begin); + ms.WriteByte((byte)CompressionMethod.Stored); + ms.Seek(0, SeekOrigin.Begin); - using (var zis = new ZipInputStream(ms)) - { - zis.IsStreamOwner = false; - var buf = new byte[32]; - zis.GetNextEntry(); + using (var zis = new ZipInputStream(ms)) + { + zis.IsStreamOwner = false; + var buf = new byte[32]; + zis.GetNextEntry(); - Assert.Throws(typeof(StreamUnsupportedException), () => - { - zis.Read(buf, 0, buf.Length); - }); - } + Assert.Throws(typeof(StreamUnsupportedException), () => + { + zis.Read(buf, 0, buf.Length); + }); } } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs index a9a7583fc..f2b3e7859 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs @@ -238,30 +238,30 @@ public void Zip64Offset() [Category("Zip")] public void BasicEncryption() { - const string TestValue = "0001000"; + const string testValue = "0001000"; var memStream = new MemoryStream(); - using (ZipFile f = new ZipFile(memStream)) + using (var zf = new ZipFile(memStream)) { - f.IsStreamOwner = false; - f.Password = "Hello"; + zf.IsStreamOwner = false; + zf.Password = "Hello"; - var m = new StringMemoryDataSource(TestValue); - f.BeginUpdate(new MemoryArchiveStorage()); - f.Add(m, "a.dat"); - f.CommitUpdate(); - Assert.IsTrue(f.TestArchive(true), "Archive test should pass"); + var m = new StringMemoryDataSource(testValue); + zf.BeginUpdate(new MemoryArchiveStorage()); + zf.Add(m, "a.dat"); + zf.CommitUpdate(); + Assert.IsTrue(zf.TestArchive(testData: true), "Archive test should pass"); } - using (ZipFile g = new ZipFile(memStream)) + using (var zf = new ZipFile(memStream)) { - g.Password = "Hello"; - ZipEntry ze = g[0]; + zf.Password = "Hello"; + var ze = zf[0]; Assert.IsTrue(ze.IsCrypted, "Entry should be encrypted"); - using (StreamReader r = new StreamReader(g.GetInputStream(0))) + using (var r = new StreamReader(zf.GetInputStream(entryIndex: 0))) { - string data = r.ReadToEnd(); - Assert.AreEqual(TestValue, data); + var data = r.ReadToEnd(); + Assert.AreEqual(testValue, data); } } } @@ -271,38 +271,38 @@ public void BasicEncryption() [Category("CreatesTempFile")] public void BasicEncryptionToDisk() { - const string TestValue = "0001000"; - string tempFile = GetTempFilePath(); + const string testValue = "0001000"; + var tempFile = GetTempFilePath(); Assert.IsNotNull(tempFile, "No permission to execute this test?"); tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - using (ZipFile f = ZipFile.Create(tempFile)) + using (var zf = ZipFile.Create(tempFile)) { - f.Password = "Hello"; + zf.Password = "Hello"; - var m = new StringMemoryDataSource(TestValue); - f.BeginUpdate(); - f.Add(m, "a.dat"); - f.CommitUpdate(); + var m = new StringMemoryDataSource(testValue); + zf.BeginUpdate(); + zf.Add(m, "a.dat"); + zf.CommitUpdate(); } - using (ZipFile f = new ZipFile(tempFile)) + using (var zf = new ZipFile(tempFile)) { - f.Password = "Hello"; - Assert.IsTrue(f.TestArchive(true), "Archive test should pass"); + zf.Password = "Hello"; + Assert.IsTrue(zf.TestArchive(testData: true), "Archive test should pass"); } - using (ZipFile g = new ZipFile(tempFile)) + using (var zf = new ZipFile(tempFile)) { - g.Password = "Hello"; - ZipEntry ze = g[0]; + zf.Password = "Hello"; + ZipEntry ze = zf[0]; Assert.IsTrue(ze.IsCrypted, "Entry should be encrypted"); - using (StreamReader r = new StreamReader(g.GetInputStream(0))) + using (var r = new StreamReader(zf.GetInputStream(entryIndex: 0))) { - string data = r.ReadToEnd(); - Assert.AreEqual(TestValue, data); + var data = r.ReadToEnd(); + Assert.AreEqual(testValue, data); } } @@ -313,14 +313,14 @@ public void BasicEncryptionToDisk() [Category("Zip")] public void AddEncryptedEntriesToExistingArchive() { - const string TestValue = "0001000"; + const string testValue = "0001000"; var memStream = new MemoryStream(); using (ZipFile f = new ZipFile(memStream)) { f.IsStreamOwner = false; f.UseZip64 = UseZip64.Off; - var m = new StringMemoryDataSource(TestValue); + var m = new StringMemoryDataSource(testValue); f.BeginUpdate(new MemoryArchiveStorage()); f.Add(m, "a.dat"); f.CommitUpdate(); @@ -335,10 +335,10 @@ public void AddEncryptedEntriesToExistingArchive() using (StreamReader r = new StreamReader(g.GetInputStream(0))) { string data = r.ReadToEnd(); - Assert.AreEqual(TestValue, data); + Assert.AreEqual(testValue, data); } - var n = new StringMemoryDataSource(TestValue); + var n = new StringMemoryDataSource(testValue); g.Password = "Axolotyl"; g.UseZip64 = UseZip64.Off; @@ -353,7 +353,7 @@ public void AddEncryptedEntriesToExistingArchive() using (StreamReader r = new StreamReader(g.GetInputStream(0))) { string data = r.ReadToEnd(); - Assert.AreEqual(TestValue, data); + Assert.AreEqual(testValue, data); } } } @@ -684,28 +684,25 @@ public void CreateEmptyArchive() [Category("CreatesTempFile")] public void CreateArchiveWithNoCompression() { - - using (var sourceFile = Utils.GetDummyFile()) - using (var zipFile = Utils.GetDummyFile(0)) + using var sourceFile = Utils.GetDummyFile(); + using var zipFile = Utils.GetDummyFile(0); + var inputContent = File.ReadAllText(sourceFile); + using (var zf = ZipFile.Create(zipFile)) { - var inputContent = File.ReadAllText(sourceFile.Filename); - using (ZipFile f = ZipFile.Create(zipFile.Filename)) - { - f.BeginUpdate(); - f.Add(sourceFile.Filename, CompressionMethod.Stored); - f.CommitUpdate(); - Assert.IsTrue(f.TestArchive(true)); - f.Close(); - } + zf.BeginUpdate(); + zf.Add(sourceFile, CompressionMethod.Stored); + zf.CommitUpdate(); + Assert.IsTrue(zf.TestArchive(testData: true)); + zf.Close(); + } - using (ZipFile f = new ZipFile(zipFile.Filename)) + using (var zf = new ZipFile(zipFile)) + { + Assert.AreEqual(1, zf.Count); + using (var sr = new StreamReader(zf.GetInputStream(zf[0]))) { - Assert.AreEqual(1, f.Count); - using (var sr = new StreamReader(f.GetInputStream(f[0]))) - { - var outputContent = sr.ReadToEnd(); - Assert.AreEqual(inputContent, outputContent, "extracted content does not match source content"); - } + var outputContent = sr.ReadToEnd(); + Assert.AreEqual(inputContent, outputContent, "extracted content does not match source content"); } } } @@ -1009,45 +1006,40 @@ public void Crypto_AddEncryptedEntryToExistingArchiveDirect() [Category("Unicode")] public void UnicodeNames() { - using (var memStream = new MemoryStream()) + using var memStream = new MemoryStream(); + using (var f = new ZipFile(memStream)) { - using (ZipFile f = new ZipFile(memStream)) - { - f.IsStreamOwner = false; - - f.BeginUpdate(new MemoryArchiveStorage()); - foreach ((string language, string name, _) in StringTesting.GetTestSamples()) - { - f.Add(new StringMemoryDataSource(language), name, - CompressionMethod.Deflated, true); - } - f.CommitUpdate(); + f.IsStreamOwner = false; - Assert.IsTrue(f.TestArchive(true)); - } - memStream.Seek(0, SeekOrigin.Begin); - using (var zf = new ZipFile(memStream)) + f.BeginUpdate(new MemoryArchiveStorage()); + foreach (var (language, name, _) in StringTesting.TestSamples) { - foreach (string name in StringTesting.Filenames) - { - //int index = zf.FindEntry(name, true); - var content = ""; - var index = zf.FindEntry(name, true); - var entry = zf[index]; + f.Add(new StringMemoryDataSource(language), name, + CompressionMethod.Deflated, useUnicodeText: true); + } + f.CommitUpdate(); - using (var entryStream = zf.GetInputStream(entry)) - using (var sr = new StreamReader(entryStream)) - { - content = sr.ReadToEnd(); - } + Assert.IsTrue(f.TestArchive(testData: true)); + } + memStream.Seek(0, SeekOrigin.Begin); + using (var zf = new ZipFile(memStream)) + { + foreach (var name in StringTesting.Filenames) + { + string content; + var index = zf.FindEntry(name, ignoreCase: true); + var entry = zf[index]; - //var content = + using (var entryStream = zf.GetInputStream(entry)) + using (var sr = new StreamReader(entryStream)) + { + content = sr.ReadToEnd(); + } - Console.WriteLine($"Entry #{index}: {name}, Content: {content}"); + TestContext.WriteLine($"Entry #{index}: {name}, Content: {content}"); - Assert.IsTrue(index >= 0); - Assert.AreEqual(name, entry.Name); - } + Assert.IsTrue(index >= 0); + Assert.AreEqual(name, entry.Name); } } } @@ -1463,57 +1455,28 @@ public void FileStreamNotClosedWhenNotOwner() } /// - /// Check that input stream is closed when construction fails and leaveOpen is false + /// Check that input stream is only closed when construction fails and leaveOpen is false /// [Test] [Category("Zip")] - public void StreamClosedOnError() + public void StreamClosedOnError([Values(true, false)] bool leaveOpen) { var ms = new TrackedMemoryStream(new byte[32]); Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed initially"); - bool blewUp = false; - try - { - using (var zipFile = new ZipFile(ms, false)) - { - Assert.Fail("Exception not thrown"); - } - } - catch + Assert.Throws(() => { - blewUp = true; - } + using var zf = new ZipFile(ms, leaveOpen); + }, "Should have failed to load the file"); - Assert.IsTrue(blewUp, "Should have failed to load the file"); - Assert.IsTrue(ms.IsClosed, "Underlying stream should be closed"); - } - - /// - /// Check that input stream is not closed when construction fails and leaveOpen is true - /// - [Test] - [Category("Zip")] - public void StreamNotClosedOnError() - { - var ms = new TrackedMemoryStream(new byte[32]); - - Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed initially"); - bool blewUp = false; - try + if (leaveOpen) { - using (var zipFile = new ZipFile(ms, true)) - { - Assert.Fail("Exception not thrown"); - } + Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed"); } - catch + else { - blewUp = true; + Assert.IsTrue(ms.IsClosed, "Underlying stream should be closed"); } - - Assert.IsTrue(blewUp, "Should have failed to load the file"); - Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed"); } [Test] @@ -1586,17 +1549,15 @@ public void HostSystemPersistedFromZipFile() public void AddingAnAESEncryptedEntryShouldThrow() { var memStream = new MemoryStream(); - using (ZipFile zof = new ZipFile(memStream)) + using var zof = new ZipFile(memStream); + var entry = new ZipEntry("test") { - var entry = new ZipEntry("test") - { - AESKeySize = 256 - }; + AESKeySize = 256, + }; - zof.BeginUpdate(); - var exception = Assert.Throws(() => zof.Add(new StringMemoryDataSource("foo"), entry)); - Assert.That(exception.Message, Is.EqualTo("Creation of AES encrypted entries is not supported")); - } + zof.BeginUpdate(); + var exception = Assert.Throws(() => zof.Add(new StringMemoryDataSource("foo"), entry)); + Assert.That(exception?.Message, Is.EqualTo("Creation of AES encrypted entries is not supported")); } /// @@ -1608,35 +1569,33 @@ public void AddingAnAESEncryptedEntryShouldThrow() public void AddFileWithAlternateName() { // Create a unique name that will be different from the file name - string fileName = Guid.NewGuid().ToString(); + var fileName = Utils.GetDummyFileName(); - using (var sourceFile = Utils.GetDummyFile()) - using (var outputFile = Utils.GetDummyFile(0)) + using var sourceFile = Utils.GetDummyFile(size: 16); + using var outputFile = Utils.GetTempFile(); + var inputContent = File.ReadAllText(sourceFile); + using (var zf = ZipFile.Create(outputFile)) { - var inputContent = File.ReadAllText(sourceFile.Filename); - using (ZipFile f = ZipFile.Create(outputFile.Filename)) - { - f.BeginUpdate(); + zf.BeginUpdate(); - // Add a file with the unique display name - f.Add(sourceFile.Filename, fileName); + // Add a file with the unique display name + zf.Add(sourceFile, fileName); - f.CommitUpdate(); - f.Close(); - } + zf.CommitUpdate(); + zf.Close(); + } - using (ZipFile zipFile = new ZipFile(outputFile.Filename)) - { - Assert.That(zipFile.Count, Is.EqualTo(1)); + using (var zipFile = new ZipFile(outputFile)) + { + Assert.That(zipFile.Count, Is.EqualTo(1)); - var fileEntry = zipFile.GetEntry(fileName); - Assert.That(fileEntry, Is.Not.Null); + var fileEntry = zipFile.GetEntry(fileName); + Assert.That(fileEntry, Is.Not.Null); - using (var sr = new StreamReader(zipFile.GetInputStream(fileEntry))) - { - var outputContent = sr.ReadToEnd(); - Assert.AreEqual(inputContent, outputContent, "extracted content does not match source content"); - } + using (var sr = new StreamReader(zipFile.GetInputStream(fileEntry))) + { + var outputContent = sr.ReadToEnd(); + Assert.AreEqual(inputContent, outputContent, "extracted content does not match source content"); } } } @@ -1713,7 +1672,7 @@ public void ZipWithBZip2Compression(bool encryptEntries) [Category("Zip")] public void ShouldReadBZip2ZipCreatedBy7Zip() { - const string BZip2CompressedZipCreatedBy7Zip = + const string bZip2CompressedZipCreatedBy7Zip = "UEsDBC4AAAAMAIa50U4/rHf5qwAAAK8AAAAJAAAASGVsbG8udHh0QlpoOTFBWSZTWTL8pwYAA" + "BWfgEhlUAAiLUgQP+feMCAAiCKaeiaBobU9JiaAMGmoak9GmRNqPUDQ9T1PQsz/t9B6YvEdvF" + "5dhwXzGE1ooO41A6TtATBEFxFUq6trGtUcSJDyWWWj/S2VwY15fy3IqHi3hHUS+K76zdoDzQa" + @@ -1721,26 +1680,20 @@ public void ShouldReadBZip2ZipCreatedBy7Zip() "AAwAhrnRTj+sd/mrAAAArwAAAAkAJAAAAAAAAAAgAAAAAAAAAEhlbGxvLnR4dAoAIAAAAAAAA" + "QAYAO97MLZZJdUB73swtlkl1QEK0UTFWCXVAVBLBQYAAAAAAQABAFsAAADSAAAAAAA="; - const string OriginalText = + const string originalText = "SharpZipLib (#ziplib, formerly NZipLib) is a compression library that supports Zip files using both stored and deflate compression methods, PKZIP 2.0 style and AES encryption."; - var fileBytes = System.Convert.FromBase64String(BZip2CompressedZipCreatedBy7Zip); + var fileBytes = Convert.FromBase64String(bZip2CompressedZipCreatedBy7Zip); - using (var input = new MemoryStream(fileBytes, false)) - { - using (ZipFile f = new ZipFile(input)) - { - var entry = f.GetEntry("Hello.txt"); - Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.BZip2), "Compression method should be BZip2"); - Assert.That(entry.Version, Is.EqualTo(ZipConstants.VersionBZip2), "Entry version should be 46"); + using var input = new MemoryStream(fileBytes, writable: false); + using var zf = new ZipFile(input); + var entry = zf.GetEntry("Hello.txt"); + Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.BZip2), "Compression method should be BZip2"); + Assert.That(entry.Version, Is.EqualTo(ZipConstants.VersionBZip2), "Entry version should be 46"); - using (var reader = new StreamReader(f.GetInputStream(entry))) - { - string contents = reader.ReadToEnd(); - Assert.That(contents, Is.EqualTo(OriginalText), "extract string must match original string"); - } - } - } + using var reader = new StreamReader(zf.GetInputStream(entry)); + var contents = reader.ReadToEnd(); + Assert.That(contents, Is.EqualTo(originalText), "extract string must match original string"); } /// @@ -1750,7 +1703,7 @@ public void ShouldReadBZip2ZipCreatedBy7Zip() [Category("Zip")] public void ShouldReadAESBZip2ZipCreatedBy7Zip() { - const string BZip2CompressedZipCreatedBy7Zip = + const string bZip2CompressedZipCreatedBy7Zip = "UEsDBDMAAQBjAIa50U4AAAAAxwAAAK8AAAAJAAsASGVsbG8udHh0AZkHAAIAQUUDDAAYg6jqf" + "kvZClVMOtgmqKT0/8I9fMPgo96myxw9hLQUhKj1Qczi3fT7QIhAnAKU+u03nA8rCKGWmDI5Qz" + "qPREy95boQVDPwmwEsWksv3GAWzMfzZUhmB/TgIJlA34a4yP0f2ucy3/QCQYo8QcHjBtjWX5b" + @@ -1759,30 +1712,24 @@ public void ShouldReadAESBZip2ZipCreatedBy7Zip() "wAAAAkALwAAAAAAAAAgAAAAAAAAAEhlbGxvLnR4dAoAIAAAAAAAAQAYAO97MLZZJdUBYdnjul" + "kl1QEK0UTFWCXVAQGZBwACAEFFAwwAUEsFBgAAAAABAAEAZgAAAPkAAAAAAA=="; - const string OriginalText = + const string originalText = "SharpZipLib (#ziplib, formerly NZipLib) is a compression library that supports Zip files using both stored and deflate compression methods, PKZIP 2.0 style and AES encryption."; - var fileBytes = System.Convert.FromBase64String(BZip2CompressedZipCreatedBy7Zip); + var fileBytes = Convert.FromBase64String(bZip2CompressedZipCreatedBy7Zip); - using (var input = new MemoryStream(fileBytes, false)) - { - using (ZipFile f = new ZipFile(input)) - { - f.Password = "password"; + using var input = new MemoryStream(fileBytes, writable: false); + using var zf = new ZipFile(input); + zf.Password = "password"; - var entry = f.GetEntry("Hello.txt"); - Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.BZip2), "Compression method should be BZip2"); - Assert.That(entry.Version, Is.EqualTo(ZipConstants.VERSION_AES), "Entry version should be 51"); - Assert.That(entry.IsCrypted, Is.True, "Entry should be encrypted"); - Assert.That(entry.AESKeySize, Is.EqualTo(256), "AES Keysize should be 256"); + var entry = zf.GetEntry("Hello.txt"); + Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.BZip2), "Compression method should be BZip2"); + Assert.That(entry.Version, Is.EqualTo(ZipConstants.VERSION_AES), "Entry version should be 51"); + Assert.That(entry.IsCrypted, Is.True, "Entry should be encrypted"); + Assert.That(entry.AESKeySize, Is.EqualTo(256), "AES Keysize should be 256"); - using (var reader = new StreamReader(f.GetInputStream(entry))) - { - string contents = reader.ReadToEnd(); - Assert.That(contents, Is.EqualTo(OriginalText), "extract string must match original string"); - } - } - } + using var reader = new StreamReader(zf.GetInputStream(entry)); + var contents = reader.ReadToEnd(); + Assert.That(contents, Is.EqualTo(originalText), "extract string must match original string"); } ///