From 9bf5df72a69ea1adcf5e43a99708f5302bae4557 Mon Sep 17 00:00:00 2001 From: haykpetros Date: Wed, 5 Aug 2015 05:27:30 -0700 Subject: [PATCH 1/9] Added additional check to make sure that data is properly copied to array regardless fo computer/CPU platform (little-endian or big-endian). In case of big-endian platform intermediate array will be reversed prior to copying to destination array. --- SharpCompress/Utility.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SharpCompress/Utility.cs b/SharpCompress/Utility.cs index a6c05f73..6a7c4d72 100644 --- a/SharpCompress/Utility.cs +++ b/SharpCompress/Utility.cs @@ -202,6 +202,10 @@ namespace SharpCompress public static void WriteLittleEndian(byte[] array, int pos, short value) { byte[] newBytes = BitConverter.GetBytes(value); + + if (!BitConverter.IsLittleEndian) + Array.Reverse(newBytes); + Array.Copy(newBytes, 0, array, pos, newBytes.Length); } @@ -234,6 +238,10 @@ namespace SharpCompress public static void WriteLittleEndian(byte[] array, int pos, int value) { byte[] newBytes = BitConverter.GetBytes(value); + + if (!BitConverter.IsLittleEndian) + Array.Reverse(newBytes); + Array.Copy(newBytes, 0, array, pos, newBytes.Length); } From 5d8bd7b69bcc0713a5a08e3d58dea87b40e3d554 Mon Sep 17 00:00:00 2001 From: Nadya Atanasova Date: Thu, 1 Oct 2015 15:41:35 +0300 Subject: [PATCH 2/9] Use enum as flag correctly Check PreserveFileTime when file times are initialized. --- SharpCompress/Archive/IArchiveEntry.Extensions.cs | 2 +- SharpCompress/Common/ExtractOptions.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SharpCompress/Archive/IArchiveEntry.Extensions.cs b/SharpCompress/Archive/IArchiveEntry.Extensions.cs index fd98d695..91f82f68 100644 --- a/SharpCompress/Archive/IArchiveEntry.Extensions.cs +++ b/SharpCompress/Archive/IArchiveEntry.Extensions.cs @@ -90,7 +90,7 @@ namespace SharpCompress.Archive FileInfo nf = new FileInfo(destinationFileName); if (nf.Exists) { - if (options.HasFlag(ExtractOptions.PreserveAttributes)) + if (options.HasFlag(ExtractOptions.PreserveFileTime)) { if (entry.CreatedTime.HasValue) { diff --git a/SharpCompress/Common/ExtractOptions.cs b/SharpCompress/Common/ExtractOptions.cs index 99e0ca8b..0aff140e 100644 --- a/SharpCompress/Common/ExtractOptions.cs +++ b/SharpCompress/Common/ExtractOptions.cs @@ -5,26 +5,26 @@ namespace SharpCompress.Common [Flags] public enum ExtractOptions { - None, + None = 0, /// /// overwrite target if it exists /// - Overwrite, + Overwrite = 1 << 0, /// /// extract with internal directory structure /// - ExtractFullPath, + ExtractFullPath = 1 << 1, /// /// preserve file time /// - PreserveFileTime, + PreserveFileTime = 1 << 2, /// /// preserve windows file attributes /// - PreserveAttributes, + PreserveAttributes = 1 << 3, } } \ No newline at end of file From 66816ce390b801b66ee0a8a0aa4a9bdf7e9e7f85 Mon Sep 17 00:00:00 2001 From: Nadya Atanasova Date: Thu, 1 Oct 2015 17:15:37 +0300 Subject: [PATCH 3/9] Add explicit compressioninfo when writing file to zip --- SharpCompress/SharpCompress.Portable.csproj | 1 + .../SharpCompress.PortableTest.csproj | 1 + SharpCompress/SharpCompress.Unsigned.csproj | 1 + .../SharpCompress.WindowsStore.csproj | 1 + SharpCompress/SharpCompress.csproj | 1 + .../Writer/Zip/ZipCompressionInfo.cs | 47 ++++++++++++++ SharpCompress/Writer/Zip/ZipWriter.cs | 64 +++++-------------- 7 files changed, 68 insertions(+), 48 deletions(-) create mode 100644 SharpCompress/Writer/Zip/ZipCompressionInfo.cs diff --git a/SharpCompress/SharpCompress.Portable.csproj b/SharpCompress/SharpCompress.Portable.csproj index 240c14ad..49e43055 100644 --- a/SharpCompress/SharpCompress.Portable.csproj +++ b/SharpCompress/SharpCompress.Portable.csproj @@ -321,6 +321,7 @@ + diff --git a/SharpCompress/SharpCompress.PortableTest.csproj b/SharpCompress/SharpCompress.PortableTest.csproj index bced861c..d978c5de 100644 --- a/SharpCompress/SharpCompress.PortableTest.csproj +++ b/SharpCompress/SharpCompress.PortableTest.csproj @@ -371,6 +371,7 @@ + diff --git a/SharpCompress/SharpCompress.Unsigned.csproj b/SharpCompress/SharpCompress.Unsigned.csproj index 6aa172cd..0bfa9838 100644 --- a/SharpCompress/SharpCompress.Unsigned.csproj +++ b/SharpCompress/SharpCompress.Unsigned.csproj @@ -359,6 +359,7 @@ + diff --git a/SharpCompress/SharpCompress.WindowsStore.csproj b/SharpCompress/SharpCompress.WindowsStore.csproj index 0dbb616c..b5c5547b 100644 --- a/SharpCompress/SharpCompress.WindowsStore.csproj +++ b/SharpCompress/SharpCompress.WindowsStore.csproj @@ -306,6 +306,7 @@ + diff --git a/SharpCompress/SharpCompress.csproj b/SharpCompress/SharpCompress.csproj index 55c734ad..b2c2ab6b 100644 --- a/SharpCompress/SharpCompress.csproj +++ b/SharpCompress/SharpCompress.csproj @@ -359,6 +359,7 @@ + diff --git a/SharpCompress/Writer/Zip/ZipCompressionInfo.cs b/SharpCompress/Writer/Zip/ZipCompressionInfo.cs new file mode 100644 index 00000000..6c163f21 --- /dev/null +++ b/SharpCompress/Writer/Zip/ZipCompressionInfo.cs @@ -0,0 +1,47 @@ +using SharpCompress.Common; +using SharpCompress.Common.Zip; +using SharpCompress.Compressor.Deflate; + +namespace SharpCompress.Writer.Zip +{ + internal class ZipCompressionInfo + { + internal CompressionLevel DeflateCompressionLevel { get; private set; } + internal ZipCompressionMethod Compression { get; private set; } + + public ZipCompressionInfo(CompressionInfo compressionInfo) + { + switch (compressionInfo.Type) + { + case CompressionType.None: + { + this.Compression = ZipCompressionMethod.None; + } + break; + case CompressionType.Deflate: + { + this.DeflateCompressionLevel = compressionInfo.DeflateCompressionLevel; + this.Compression = ZipCompressionMethod.Deflate; + } + break; + case CompressionType.BZip2: + { + this.Compression = ZipCompressionMethod.BZip2; + } + break; + case CompressionType.LZMA: + { + this.Compression = ZipCompressionMethod.LZMA; + } + break; + case CompressionType.PPMd: + { + this.Compression = ZipCompressionMethod.PPMd; + } + break; + default: + throw new InvalidFormatException("Invalid compression method: " + compressionInfo.Type); + } + } + } +} diff --git a/SharpCompress/Writer/Zip/ZipWriter.cs b/SharpCompress/Writer/Zip/ZipWriter.cs index e65cfd87..8a2ade52 100644 --- a/SharpCompress/Writer/Zip/ZipWriter.cs +++ b/SharpCompress/Writer/Zip/ZipWriter.cs @@ -17,52 +17,18 @@ namespace SharpCompress.Writer.Zip { public class ZipWriter : AbstractWriter { - private readonly ZipCompressionMethod compression; - private readonly CompressionLevel deflateCompressionLevel; - + private readonly ZipCompressionInfo zipCompressionInfo; + private readonly PpmdProperties ppmdProperties = new PpmdProperties(); // Caching properties to speed up PPMd private readonly List entries = new List(); private readonly string zipComment; private long streamPosition; - private readonly PpmdProperties ppmdProperties; // Caching properties to speed up PPMd. - public ZipWriter(Stream destination, CompressionInfo compressionInfo, string zipComment) : base(ArchiveType.Zip) { this.zipComment = zipComment ?? string.Empty; - switch (compressionInfo.Type) - { - case CompressionType.None: - { - compression = ZipCompressionMethod.None; - } - break; - case CompressionType.Deflate: - { - compression = ZipCompressionMethod.Deflate; - deflateCompressionLevel = compressionInfo.DeflateCompressionLevel; - } - break; - case CompressionType.BZip2: - { - compression = ZipCompressionMethod.BZip2; - } - break; - case CompressionType.LZMA: - { - compression = ZipCompressionMethod.LZMA; - } - break; - case CompressionType.PPMd: - { - ppmdProperties = new PpmdProperties(); - compression = ZipCompressionMethod.PPMd; - } - break; - default: - throw new InvalidFormatException("Invalid compression method: " + compressionInfo.Type); - } + this.zipCompressionInfo = new ZipCompressionInfo(compressionInfo); InitalizeStream(destination, false); } @@ -73,7 +39,7 @@ namespace SharpCompress.Writer.Zip uint size = 0; foreach (ZipCentralDirectoryEntry entry in entries) { - size += entry.Write(OutputStream, compression); + size += entry.Write(OutputStream, zipCompressionInfo.Compression); } WriteEndRecord(size); } @@ -85,15 +51,15 @@ namespace SharpCompress.Writer.Zip Write(entryPath, source, modificationTime, null); } - public void Write(string entryPath, Stream source, DateTime? modificationTime, string comment) + public void Write(string entryPath, Stream source, DateTime? modificationTime, string comment, CompressionInfo compressionInfo = null) { - using (Stream output = WriteToStream(entryPath, modificationTime, comment)) + using (Stream output = WriteToStream(entryPath, modificationTime, comment, compressionInfo)) { source.TransferTo(output); } } - public Stream WriteToStream(string entryPath, DateTime? modificationTime, string comment) + public Stream WriteToStream(string entryPath, DateTime? modificationTime, string comment, CompressionInfo compressionInfo = null) { entryPath = NormalizeFilename(entryPath); modificationTime = modificationTime ?? DateTime.Now; @@ -105,7 +71,8 @@ namespace SharpCompress.Writer.Zip ModificationTime = modificationTime, HeaderOffset = (uint) streamPosition, }; - var headersize = (uint) WriteHeader(entryPath, modificationTime); + + var headersize = (uint)WriteHeader(entryPath, modificationTime, compressionInfo); streamPosition += headersize; return new ZipWritingStream(this, OutputStream, entry); } @@ -121,8 +88,9 @@ namespace SharpCompress.Writer.Zip return filename.Trim('/'); } - private int WriteHeader(string filename, DateTime? modificationTime) + private int WriteHeader(string filename, DateTime? modificationTime, CompressionInfo compressionInfo = null) { + var explicitZipCompressionInfo = compressionInfo != null ? new ZipCompressionInfo(compressionInfo) : this.zipCompressionInfo; byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename); OutputStream.Write(BitConverter.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4); @@ -131,13 +99,13 @@ namespace SharpCompress.Writer.Zip if (!OutputStream.CanSeek) { flags |= HeaderFlags.UsePostDataDescriptor; - if (compression == ZipCompressionMethod.LZMA) + if (explicitZipCompressionInfo.Compression == ZipCompressionMethod.LZMA) { flags |= HeaderFlags.Bit1; // eos marker } } OutputStream.Write(BitConverter.GetBytes((ushort) flags), 0, 2); - OutputStream.Write(BitConverter.GetBytes((ushort) compression), 0, 2); // zipping method + OutputStream.Write(BitConverter.GetBytes((ushort)explicitZipCompressionInfo.Compression), 0, 2); // zipping method OutputStream.Write(BitConverter.GetBytes(modificationTime.DateTimeToDosTime()), 0, 4); // zipping date and time OutputStream.Write(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 12); @@ -220,7 +188,7 @@ namespace SharpCompress.Writer.Zip { counting = new CountingWritableSubStream(writeStream); Stream output = counting; - switch (writer.compression) + switch (writer.zipCompressionInfo.Compression) { case ZipCompressionMethod.None: { @@ -228,7 +196,7 @@ namespace SharpCompress.Writer.Zip } case ZipCompressionMethod.Deflate: { - return new DeflateStream(counting, CompressionMode.Compress, writer.deflateCompressionLevel, + return new DeflateStream(counting, CompressionMode.Compress, writer.zipCompressionInfo.DeflateCompressionLevel, true); } case ZipCompressionMethod.BZip2: @@ -254,7 +222,7 @@ namespace SharpCompress.Writer.Zip } default: { - throw new NotSupportedException("CompressionMethod: " + writer.compression); + throw new NotSupportedException("CompressionMethod: " + writer.zipCompressionInfo.Compression); } } } From 13bbb202c7a58a4f8139b0d9fd6babe667618ba7 Mon Sep 17 00:00:00 2001 From: twirpx Date: Thu, 19 Nov 2015 21:06:56 +0500 Subject: [PATCH 4/9] Changed MAX_ITERATIONS_FOR_DIRECTORY_HEADER to deal with archives that have larger comments --- SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs b/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs index 2ac9a165..61c96393 100644 --- a/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs +++ b/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs @@ -8,7 +8,7 @@ namespace SharpCompress.Common.Zip { internal class SeekableZipHeaderFactory : ZipHeaderFactory { - private const int MAX_ITERATIONS_FOR_DIRECTORY_HEADER = 1000; + private const int MAX_ITERATIONS_FOR_DIRECTORY_HEADER = 4096; internal SeekableZipHeaderFactory(string password) : base(StreamingMode.Seekable, password) From 18bd8102281c04c7eb09ecfdd984d7382b629f2c Mon Sep 17 00:00:00 2001 From: twirpx Date: Thu, 19 Nov 2015 21:07:52 +0500 Subject: [PATCH 5/9] Fixed non-compilable statements --- SharpCompress/Compressor/Deflate/DeflateManager.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SharpCompress/Compressor/Deflate/DeflateManager.cs b/SharpCompress/Compressor/Deflate/DeflateManager.cs index dba464ac..b9302d13 100644 --- a/SharpCompress/Compressor/Deflate/DeflateManager.cs +++ b/SharpCompress/Compressor/Deflate/DeflateManager.cs @@ -677,10 +677,10 @@ namespace SharpCompress.Compressor.Deflate { if (bi_valid > (int) Buf_size - len) { - //int val = value; // bi_buf |= (val << bi_valid); + int x = (value << bi_valid) & 0xffff; + bi_buf = (short)((int)bi_buf | x); - bi_buf |= (short) ((value << bi_valid) & 0xffff); //put_short(bi_buf); pending[pendingCount++] = (byte) bi_buf; pending[pendingCount++] = (byte) (bi_buf >> 8); @@ -691,8 +691,10 @@ namespace SharpCompress.Compressor.Deflate } else { - // bi_buf |= (value) << bi_valid; - bi_buf |= (short) ((value << bi_valid) & 0xffff); + // bi_buf |= (val << bi_valid); + int x = (value << bi_valid) & 0xffff; + bi_buf = (short)((int)bi_buf | x); + bi_valid += len; } } From 0f12a073af4486509dfd777da1854efb5dc571ee Mon Sep 17 00:00:00 2001 From: twirpx Date: Thu, 19 Nov 2015 21:08:55 +0500 Subject: [PATCH 6/9] Eliminated "throw - catch all" logic in ZipArchive --- SharpCompress/Archive/Zip/ZipArchive.cs | 2 +- .../Common/Zip/StreamingZipHeaderFactory.cs | 21 +++++++++---------- SharpCompress/Common/Zip/ZipHeaderFactory.cs | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/SharpCompress/Archive/Zip/ZipArchive.cs b/SharpCompress/Archive/Zip/ZipArchive.cs index 61a5e3f8..9b30a37f 100644 --- a/SharpCompress/Archive/Zip/ZipArchive.cs +++ b/SharpCompress/Archive/Zip/ZipArchive.cs @@ -116,7 +116,7 @@ namespace SharpCompress.Archive.Zip try { ZipHeader header = - headerFactory.ReadStreamHeader(stream).FirstOrDefault(x => x.ZipHeaderType != ZipHeaderType.Split); + headerFactory.ReadStreamHeader(stream).FirstOrDefault(x => x != null && x.ZipHeaderType != ZipHeaderType.Split); if (header == null) { return false; diff --git a/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs index 6bcffa1d..c9f1e182 100644 --- a/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs +++ b/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs @@ -45,18 +45,17 @@ namespace SharpCompress.Common.Zip lastEntryHeader = null; uint headerBytes = reader.ReadUInt32(); header = ReadHeader(headerBytes, reader); - - //entry could be zero bytes so we need to know that. - if (header.ZipHeaderType == ZipHeaderType.LocalEntry) - { - bool isRecording = rewindableStream.IsRecording; - if (!isRecording) - { - rewindableStream.StartRecording(); + if (header != null) { + // entry could be zero bytes so we need to know that. + if(header.ZipHeaderType == ZipHeaderType.LocalEntry) { + bool isRecording = rewindableStream.IsRecording; + if (!isRecording) { + rewindableStream.StartRecording(); + } + uint nextHeaderBytes = reader.ReadUInt32(); + header.HasData = !IsHeader(nextHeaderBytes); + rewindableStream.Rewind(!isRecording); } - uint nextHeaderBytes = reader.ReadUInt32(); - header.HasData = !IsHeader(nextHeaderBytes); - rewindableStream.Rewind(!isRecording); } yield return header; } diff --git a/SharpCompress/Common/Zip/ZipHeaderFactory.cs b/SharpCompress/Common/Zip/ZipHeaderFactory.cs index 842d77b8..f6281738 100644 --- a/SharpCompress/Common/Zip/ZipHeaderFactory.cs +++ b/SharpCompress/Common/Zip/ZipHeaderFactory.cs @@ -87,7 +87,7 @@ namespace SharpCompress.Common.Zip return entry; } default: - throw new NotSupportedException("Unknown header: " + headerBytes); + return null; } } From cd8ea28576239d31ecbd0cc3a62aad25498d2fc7 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 20 Nov 2015 18:59:15 +0000 Subject: [PATCH 7/9] last write time shouldn't equal...right? --- SharpCompress.Test/TestBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharpCompress.Test/TestBase.cs b/SharpCompress.Test/TestBase.cs index dc264c02..1f074198 100644 --- a/SharpCompress.Test/TestBase.cs +++ b/SharpCompress.Test/TestBase.cs @@ -202,7 +202,7 @@ namespace SharpCompress.Test { FileInfo fi1 = new FileInfo(file1); FileInfo fi2 = new FileInfo(file2); - Assert.AreEqual(fi1.LastWriteTime, fi2.LastWriteTime); + Assert.AreNotEqual(fi1.LastWriteTime, fi2.LastWriteTime); Assert.AreEqual(fi1.Attributes, fi2.Attributes); } From 2b5ee6e8cbfe617166d3988945b16d3f328ca043 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 20 Nov 2015 18:59:29 +0000 Subject: [PATCH 8/9] resharper update --- SharpCompress/sharpcompress.DotSettings | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SharpCompress/sharpcompress.DotSettings b/SharpCompress/sharpcompress.DotSettings index 68dda795..cb391bb6 100644 --- a/SharpCompress/sharpcompress.DotSettings +++ b/SharpCompress/sharpcompress.DotSettings @@ -128,5 +128,7 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True True + True True \ No newline at end of file From 27a4f78712efd9fdb3f4d62d57a2da4d9dca4db0 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 20 Nov 2015 18:59:43 +0000 Subject: [PATCH 9/9] version 0.11.2 --- SharpCompress/VersionInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharpCompress/VersionInfo.cs b/SharpCompress/VersionInfo.cs index 586dd882..090db4ee 100644 --- a/SharpCompress/VersionInfo.cs +++ b/SharpCompress/VersionInfo.cs @@ -11,5 +11,5 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © Adam Hathcock")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.10.3.0")] -[assembly: AssemblyFileVersion("0.10.3.0")] \ No newline at end of file +[assembly: AssemblyVersion("0.11.2.0")] +[assembly: AssemblyFileVersion("0.11.2.0")] \ No newline at end of file