diff --git a/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs b/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs index 16c01d36..cce5acc9 100644 --- a/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs +++ b/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Linq; namespace SharpCompress.Common.Zip.Headers { @@ -34,6 +35,12 @@ namespace SharpCompress.Common.Zip.Headers byte[] comment = reader.ReadBytes(commentLength); Comment = DecodeString(comment); LoadExtra(extra); + + var unicodePathExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnicodePathExtraField); + if (unicodePathExtra != null) + { + Name = ((ExtraUnicodePathExtraField)unicodePathExtra).UnicodeName; + } } internal override void Write(BinaryWriter writer) diff --git a/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs b/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs index 3f423df9..0146c89e 100644 --- a/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs +++ b/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs @@ -1,19 +1,8 @@ using System.IO; +using System.Linq; namespace SharpCompress.Common.Zip.Headers { - internal enum ExtraDataType : ushort - { - WinZipAes = 0x9901, - } - - internal class ExtraData - { - internal ExtraDataType Type { get; set; } - internal ushort Length { get; set; } - internal byte[] DataBytes { get; set; } - } - internal class LocalEntryHeader : ZipFileEntry { public LocalEntryHeader() @@ -37,6 +26,12 @@ namespace SharpCompress.Common.Zip.Headers byte[] extra = reader.ReadBytes(extraLength); Name = DecodeString(name); LoadExtra(extra); + + var unicodePathExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnicodePathExtraField); + if (unicodePathExtra!=null) + { + Name = ((ExtraUnicodePathExtraField) unicodePathExtra).UnicodeName; + } } internal override void Write(BinaryWriter writer) diff --git a/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs b/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs new file mode 100644 index 00000000..d7741001 --- /dev/null +++ b/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs @@ -0,0 +1,75 @@ +using System; +using System.Text; + +namespace SharpCompress.Common.Zip.Headers +{ + internal enum ExtraDataType : ushort + { + WinZipAes = 0x9901, + + NotImplementedExtraData = 0xFFFF, + // Third Party Mappings + // -Info-ZIP Unicode Path Extra Field + UnicodePathExtraField = 0x7075 + } + + internal class ExtraData + { + internal ExtraDataType Type { get; set; } + internal ushort Length { get; set; } + internal byte[] DataBytes { get; set; } + } + + internal class ExtraUnicodePathExtraField : ExtraData + { + internal byte Version + { + get { return this.DataBytes[0]; } + } + + internal byte[] NameCRC32 + { + get + { + var crc = new byte[4]; + Buffer.BlockCopy(this.DataBytes, 1, crc, 0, 4); + return crc; + } + } + + internal string UnicodeName + { + get + { + // PathNamelength = dataLength - Version(1 byte) - NameCRC32(4 bytes) + var length = this.Length - 5; + var nameStr = Encoding.UTF8.GetString(this.DataBytes, 5, length); + return nameStr; + } + } + } + + internal static class LocalEntryHeaderExtraFactory + { + internal static ExtraData Create(ExtraDataType type,ushort length, byte[] extraData) + { + switch (type) + { + case ExtraDataType.UnicodePathExtraField: + return new ExtraUnicodePathExtraField() + { + Type = type, + Length = length, + DataBytes = extraData + }; + default: + return new ExtraData + { + Type = type, + Length = length, + DataBytes = extraData + }; + } + } + } +} diff --git a/SharpCompress/Common/Zip/Headers/ZipFileEntry..cs b/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs similarity index 86% rename from SharpCompress/Common/Zip/Headers/ZipFileEntry..cs rename to SharpCompress/Common/Zip/Headers/ZipFileEntry.cs index e6956603..c3bca83b 100644 --- a/SharpCompress/Common/Zip/Headers/ZipFileEntry..cs +++ b/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs @@ -13,7 +13,6 @@ namespace SharpCompress.Common.Zip.Headers Extra = new List(); } - internal bool IsDirectory { get { return Name.EndsWith("/"); } @@ -25,6 +24,7 @@ namespace SharpCompress.Common.Zip.Headers { return Encoding.UTF8.GetString(str, 0, str.Length); } + return ArchiveEncoding.Default.GetString(str, 0, str.Length); } @@ -71,17 +71,14 @@ namespace SharpCompress.Common.Zip.Headers ExtraDataType type = (ExtraDataType) BitConverter.ToUInt16(extra, i); if (!Enum.IsDefined(typeof (ExtraDataType), type)) { - return; + type = ExtraDataType.NotImplementedExtraData; } + ushort length = BitConverter.ToUInt16(extra, i + 2); byte[] data = new byte[length]; Buffer.BlockCopy(extra, i + 4, data, 0, length); - Extra.Add(new ExtraData - { - Type = type, - Length = length, - DataBytes = data - }); + Extra.Add(LocalEntryHeaderExtraFactory.Create(type,length,data)); + i += length + 4; } } diff --git a/SharpCompress/SharpCompress.csproj b/SharpCompress/SharpCompress.csproj index b20ff3da..c97874de 100644 --- a/SharpCompress/SharpCompress.csproj +++ b/SharpCompress/SharpCompress.csproj @@ -76,7 +76,7 @@ true - true + false SharpCompress.pfx @@ -150,8 +150,9 @@ + - +