diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
index b655bca19..03cac7358 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
@@ -379,7 +379,7 @@ public override int Read(byte[] buffer, int offset, int count)
}
///
- /// Flushes the stream by calling Flush on the deflater and then
+ /// Flushes the stream by calling Flush on the deflater and then
/// on the underlying stream. This ensures that all bytes are flushed.
///
public override void Flush()
diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs
index 003881988..51618968c 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs
@@ -1069,10 +1069,15 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
bool testHeader = (tests & HeaderTest.Header) != 0;
bool testData = (tests & HeaderTest.Extract) != 0;
- baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin);
- if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature)
+ var entryAbsOffset = offsetOfFirstEntry + entry.Offset;
+
+ baseStream_.Seek(entryAbsOffset, SeekOrigin.Begin);
+ var signature = (int)ReadLEUint();
+
+ if (signature != ZipConstants.LocalHeaderSignature)
{
- throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset));
+ throw new ZipException(string.Format("Wrong local header signature at 0x{0:x}, expected 0x{1:x8}, actual 0x{2:x8}",
+ entryAbsOffset, ZipConstants.LocalHeaderSignature, signature));
}
var extractVersion = (short)(ReadLEUshort() & 0x00ff);
diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs
index c3dd31af2..b9f1965dd 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs
@@ -887,6 +887,22 @@ public override void Finish()
entries = null;
}
+ ///
+ /// Flushes the stream by calling Flush on the deflater stream unless
+ /// the current compression method is . Then it flushes the underlying output stream.
+ ///
+ public override void Flush()
+ {
+ if(curMethod == CompressionMethod.Stored)
+ {
+ baseOutputStream_.Flush();
+ }
+ else
+ {
+ base.Flush();
+ }
+ }
+
#region Instance Fields
///
diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/RingBuffer.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/RingBuffer.cs
index be351ae10..d4b75e3cf 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/RingBuffer.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/RingBuffer.cs
@@ -405,6 +405,7 @@ public byte this[int index]
}
[TestFixture]
+ [Explicit("Meta tests (for ringbuffer)")]
public class ExerciseBuffer
{
[Test]
diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs
index 9a564c3c8..9c582daa6 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs
@@ -1,6 +1,7 @@
using NUnit.Framework;
using System;
using System.IO;
+using System.Text;
namespace ICSharpCode.SharpZipLib.Tests.TestSupport
{
@@ -9,6 +10,8 @@ namespace ICSharpCode.SharpZipLib.Tests.TestSupport
///
public static class Utils
{
+ public static int DummyContentLength = 16;
+
private static Random random = new Random();
private static void Compare(byte[] a, byte[] b)
@@ -32,16 +35,24 @@ private static void Compare(byte[] a, byte[] b)
public static void WriteDummyData(string fileName, int size = -1)
{
- if (size < 0)
+ using(var fs = File.OpenWrite(fileName))
{
- File.WriteAllText(fileName, DateTime.UtcNow.Ticks.ToString("x16"));
+ WriteDummyData(fs, size);
}
- else if (size > 0)
+ }
+
+ public static void WriteDummyData(Stream stream, int size = -1)
+ {
+ var bytes = (size < 0)
+ ? Encoding.ASCII.GetBytes(DateTime.UtcNow.Ticks.ToString("x16"))
+ : new byte[size];
+
+ if(size > 0)
{
- var bytes = Array.CreateInstance(typeof(byte), size) as byte[];
random.NextBytes(bytes);
- File.WriteAllBytes(fileName, bytes);
}
+
+ stream.Write(bytes, 0, bytes.Length);
}
public static TempFile GetDummyFile(int size = -1)
@@ -85,7 +96,10 @@ protected virtual void Dispose(bool disposing)
}
public void Dispose()
- => Dispose(true);
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
#endregion IDisposable Support
}
@@ -122,7 +136,10 @@ protected virtual void Dispose(bool disposing)
}
public void Dispose()
- => Dispose(true);
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
internal string CreateDummyFile(int size = -1)
=> CreateDummyFile(GetDummyFileName(), size);
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
index f16000699..25d53573f 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
@@ -93,6 +93,32 @@ public void ExtractEmptyDirectories()
Assert.IsTrue(Directory.Exists(targetDir), "Empty directory should be created");
}
+ [Test]
+ [Category("Zip")]
+ [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");
+
+ var targetFile = Path.Combine(targetDir.Fullpath, 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");
+ }
+ }
+
[Test]
[Category("Zip")]
public void Encryption()
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
index a2a9f635b..11aa1b213 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
@@ -1,4 +1,5 @@
-using ICSharpCode.SharpZipLib.Tests.TestSupport;
+using ICSharpCode.SharpZipLib.Core;
+using ICSharpCode.SharpZipLib.Tests.TestSupport;
using ICSharpCode.SharpZipLib.Zip;
using NUnit.Framework;
using System.IO;
@@ -190,6 +191,53 @@ public void EmptyZipEntries()
Assert.AreEqual(extractCount, 0, "No data should be read from empty entries");
}
+ [Test]
+ [Category("Zip")]
+ public void WriteZipStreamWithNoCompression([Values(0, 1, 256)] int contentLength)
+ {
+ var buffer = new byte[255];
+
+ using (var dummyZip = Utils.GetDummyFile(0))
+ using (var inputFile = Utils.GetDummyFile(contentLength))
+ {
+ using (var zipFileStream = File.OpenWrite(dummyZip.Filename))
+ using (var zipOutputStream = new ZipOutputStream(zipFileStream))
+ using (var inputFileStream = File.OpenRead(inputFile.Filename))
+ {
+ zipOutputStream.PutNextEntry(new ZipEntry(inputFile.Filename)
+ {
+ CompressionMethod = CompressionMethod.Stored,
+ });
+
+ StreamUtils.Copy(inputFileStream, zipOutputStream, buffer);
+ }
+
+ using (var zf = new ZipFile(dummyZip.Filename))
+ {
+ var inputBytes = File.ReadAllBytes(inputFile.Filename);
+
+ var inputFileName = ZipEntry.CleanName(inputFile.Filename);
+ var entry = zf.GetEntry(inputFileName);
+ Assert.IsNotNull(entry, "No entry matching source file \"{0}\" found in archive, found \"{1}\"", inputFileName, zf[0].Name);
+
+ Assert.DoesNotThrow(() =>
+ {
+ using (var entryStream = zf.GetInputStream(entry))
+ {
+ var outputBytes = new byte[entryStream.Length];
+ entryStream.Read(outputBytes, 0, outputBytes.Length);
+
+ 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");
+ }
+
+
+ }
+ }
+
///
/// Empty zips can be created and read?
///
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs
index 6d9a1ea9c..9bae7f772 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs
@@ -615,6 +615,37 @@ public void CreateEmptyArchive()
File.Delete(tempFile);
}
+ [Test]
+ [Category("Zip")]
+ [Category("CreatesTempFile")]
+ public void CreateArchiveWithNoCompression()
+ {
+
+ using (var sourceFile = Utils.GetDummyFile())
+ using (var zipFile = Utils.GetDummyFile(0))
+ {
+ 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();
+ }
+
+ using (ZipFile f = new ZipFile(zipFile.Filename))
+ {
+ 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");
+ }
+ }
+ }
+ }
+
///
/// Check that ZipFile finds entries when its got a long comment
///
@@ -1089,8 +1120,8 @@ public void NameFactory()
var names = new string[]
{
"\u030A\u03B0", // Greek
- "\u0680\u0685" // Arabic
- };
+ "\u0680\u0685" // Arabic
+ };
foreach (string name in names)
{