Exemple #1
0
 private void ProcessAESExtraData(ZipExtraData extraData)
 {
     if (!extraData.Find(0x9901))
     {
         throw new ZipException("AES Extra Data missing");
     }
     versionToExtract = 0x33;
     Flags |= 0x40;
     int valueLength = extraData.ValueLength;
     if (valueLength < 7)
     {
         throw new ZipException("AES Extra Data Length " + valueLength + " invalid.");
     }
     extraData.ReadShort();
     extraData.ReadShort();
     int num3 = extraData.ReadByte();
     int num4 = extraData.ReadShort();
     _aesEncryptionStrength = num3;
     method = (CompressionMethod)num4;
 }
Exemple #2
0
 internal void ProcessExtraData(bool localHeader)
 {
     ZipExtraData extraData = new ZipExtraData(extra);
     if (extraData.Find(1))
     {
         forceZip64_ = true;
         if (extraData.ValueLength < 4)
         {
             throw new ZipException("Extra data extended Zip64 information length is invalid");
         }
         if (localHeader || (size == 0xffffffffL))
         {
             size = (ulong)extraData.ReadLong();
         }
         if (localHeader || (compressedSize == 0xffffffffL))
         {
             compressedSize = (ulong)extraData.ReadLong();
         }
         if (!localHeader && (offset == 0xffffffffL))
         {
             offset = extraData.ReadLong();
         }
     }
     else if (((versionToExtract & 0xff) >= 0x2d) && ((size == 0xffffffffL) || (compressedSize == 0xffffffffL)))
     {
         throw new ZipException("Zip64 Extended information required but is missing.");
     }
     if (extraData.Find(10))
     {
         if (extraData.ValueLength < 4)
         {
             throw new ZipException("NTFS Extra data invalid");
         }
         extraData.ReadInt();
         while (extraData.UnreadCount >= 4)
         {
             int num = extraData.ReadShort();
             int amount = extraData.ReadShort();
             if (num == 1)
             {
                 if (amount >= 0x18)
                 {
                     long fileTime = extraData.ReadLong();
                     extraData.ReadLong();
                     extraData.ReadLong();
                     DateTime = DateTime.FromFileTime(fileTime);
                 }
                 break;
             }
             extraData.Skip(amount);
         }
     }
     else if (extraData.Find(0x5455))
     {
         int valueLength = extraData.ValueLength;
         if (((extraData.ReadByte() & 1) != 0) && (valueLength >= 5))
         {
             int seconds = extraData.ReadInt();
             DateTime time = new DateTime(0x7b2, 1, 1, 0, 0, 0);
             DateTime = (time.ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime();
         }
     }
     if (method == CompressionMethod.WinZipAES)
     {
         ProcessAESExtraData(extraData);
     }
 }
Exemple #3
0
 private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
 {
     lock (baseStream_)
     {
         bool flag = (tests & HeaderTest.Header) != 0;
         bool flag2 = (tests & HeaderTest.Extract) != 0;
         baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin);
         if (ReadLEUint() != 0x4034b50)
         {
             throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset));
         }
         short num = (short)ReadLEUshort();
         short flags = (short)ReadLEUshort();
         short num3 = (short)ReadLEUshort();
         short num4 = (short)ReadLEUshort();
         short num5 = (short)ReadLEUshort();
         uint num6 = ReadLEUint();
         long num7 = ReadLEUint();
         long num8 = ReadLEUint();
         int num9 = ReadLEUshort();
         int num10 = ReadLEUshort();
         byte[] buffer = new byte[num9];
         StreamUtils.ReadFully(baseStream_, buffer);
         byte[] buffer2 = new byte[num10];
         StreamUtils.ReadFully(baseStream_, buffer2);
         ZipExtraData data = new ZipExtraData(buffer2);
         if (data.Find(1))
         {
             num8 = data.ReadLong();
             num7 = data.ReadLong();
             if ((flags & 8) != 0)
             {
                 if ((num8 != -1L) && (num8 != entry.Size))
                 {
                     throw new ZipException("Size invalid for descriptor");
                 }
                 if ((num7 != -1L) && (num7 != entry.CompressedSize))
                 {
                     throw new ZipException("Compressed size invalid for descriptor");
                 }
             }
         }
         else if ((num >= 0x2d) && ((((uint)num8) == uint.MaxValue) || (((uint)num7) == uint.MaxValue)))
         {
             throw new ZipException("Required Zip64 extended information missing");
         }
         if (flag2 && entry.IsFile)
         {
             if (!entry.IsCompressionMethodSupported())
             {
                 throw new ZipException("Compression method not supported");
             }
             if ((num > 0x33) || ((num > 20) && (num < 0x2d)))
             {
                 throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", num));
             }
             if ((flags & 0x3060) != 0)
             {
                 throw new ZipException("The library does not support the zip version required to extract this entry");
             }
         }
         if (flag)
         {
             if (((((num <= 0x3f) && (num != 10)) && ((num != 11) && (num != 20))) && (((num != 0x15) && (num != 0x19)) && ((num != 0x1b) && (num != 0x2d)))) && ((((num != 0x2e) && (num != 50)) && ((num != 0x33) && (num != 0x34))) && (((num != 0x3d) && (num != 0x3e)) && (num != 0x3f))))
             {
                 throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", num));
             }
             if ((flags & 0xc010) != 0)
             {
                 throw new ZipException("Reserved bit flags cannot be set.");
             }
             if (((flags & 1) != 0) && (num < 20))
             {
                 throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", num));
             }
             if ((flags & 0x40) != 0)
             {
                 if ((flags & 1) == 0)
                 {
                     throw new ZipException("Strong encryption flag set but encryption flag is not set");
                 }
                 if (num < 50)
                 {
                     throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", num));
                 }
             }
             if (((flags & 0x20) != 0) && (num < 0x1b))
             {
                 throw new ZipException(string.Format("Patched data requires higher version than ({0})", num));
             }
             if (flags != entry.Flags)
             {
                 throw new ZipException("Central header/local header flags mismatch");
             }
             if (entry.CompressionMethod != ((CompressionMethod)num3))
             {
                 throw new ZipException("Central header/local header compression method mismatch");
             }
             if (entry.Version != num)
             {
                 throw new ZipException("Extract version mismatch");
             }
             if (((flags & 0x40) != 0) && (num < 0x3e))
             {
                 throw new ZipException("Strong encryption flag set but version not high enough");
             }
             if (((flags & 0x2000) != 0) && ((num4 != 0) || (num5 != 0)))
             {
                 throw new ZipException("Header masked set but date/time values non-zero");
             }
             if (((flags & 8) == 0) && (num6 != ((uint)entry.Crc)))
             {
                 throw new ZipException("Central header/local header crc mismatch");
             }
             if (((num8 == 0L) && (num7 == 0L)) && (num6 != 0))
             {
                 throw new ZipException("Invalid CRC for empty entry");
             }
             if (entry.Name.Length > num9)
             {
                 throw new ZipException("File name length mismatch");
             }
             string name = ZipConstants.ConvertToStringExt(flags, buffer);
             if (name != entry.Name)
             {
                 throw new ZipException("Central header and local header file name mismatch");
             }
             if (entry.IsDirectory)
             {
                 if (num8 > 0L)
                 {
                     throw new ZipException("Directory cannot have size");
                 }
                 if (entry.IsCrypted)
                 {
                     if (num7 > 14L)
                     {
                         throw new ZipException("Directory compressed size invalid");
                     }
                 }
                 else if (num7 > 2L)
                 {
                     throw new ZipException("Directory compressed size invalid");
                 }
             }
             if (!ZipNameTransform.IsValidName(name, true))
             {
                 throw new ZipException("Name is invalid");
             }
         }
         if ((((flags & 8) == 0) || (num8 > 0L)) || (num7 > 0L))
         {
             if (num8 != entry.Size)
             {
                 throw new ZipException(string.Format("Size mismatch between central header({0}) and local header({1})", entry.Size, num8));
             }
             if (((num7 != entry.CompressedSize) && (num7 != 0xffffffffL)) && (num7 != -1L))
             {
                 throw new ZipException(string.Format("Compressed size mismatch between central header({0}) and local header({1})", entry.CompressedSize, num7));
             }
         }
         int num11 = num9 + num10;
         return (((offsetOfFirstEntry + entry.Offset) + 30L) + num11);
     }
 }
Exemple #4
0
        private void WriteLocalEntryHeader(ZipUpdate update)
        {
            ZipEntry outEntry = update.OutEntry;
            outEntry.Offset = baseStream_.Position;
            if (update.Command != UpdateCommand.Copy)
            {
                if (outEntry.CompressionMethod == CompressionMethod.Deflated)
                {
                    if (outEntry.Size == 0L)
                    {
                        outEntry.CompressedSize = outEntry.Size;
                        outEntry.Crc = 0L;
                        outEntry.CompressionMethod = CompressionMethod.Stored;
                    }
                }
                else if (outEntry.CompressionMethod == CompressionMethod.Stored)
                {
                    outEntry.Flags &= -9;
                }
                if (HaveKeys)
                {
                    outEntry.IsCrypted = true;
                    if (outEntry.Crc < 0L)
                    {
                        outEntry.Flags |= 8;
                    }
                }
                else
                {
                    outEntry.IsCrypted = false;
                }
                switch (useZip64_)
                {
                    case UseZip64.On:
                        outEntry.ForceZip64();
                        break;

                    case UseZip64.Dynamic:
                        if (outEntry.Size < 0L)
                        {
                            outEntry.ForceZip64();
                        }
                        break;
                }
            }
            WriteLEInt(0x4034b50);
            WriteLEShort(outEntry.Version);
            WriteLEShort(outEntry.Flags);
            WriteLEShort((byte)outEntry.CompressionMethod);
            WriteLEInt((int)outEntry.DosTime);
            if (!outEntry.HasCrc)
            {
                update.CrcPatchOffset = baseStream_.Position;
                WriteLEInt(0);
            }
            else
            {
                WriteLEInt((int)outEntry.Crc);
            }
            if (outEntry.LocalHeaderRequiresZip64)
            {
                WriteLEInt(-1);
                WriteLEInt(-1);
            }
            else
            {
                if ((outEntry.CompressedSize < 0L) || (outEntry.Size < 0L))
                {
                    update.SizePatchOffset = baseStream_.Position;
                }
                WriteLEInt((int)outEntry.CompressedSize);
                WriteLEInt((int)outEntry.Size);
            }
            byte[] buffer = ZipConstants.ConvertToArray(outEntry.Flags, outEntry.Name);
            if (buffer.Length > 0xffff)
            {
                throw new ZipException("Entry name too long.");
            }
            ZipExtraData data = new ZipExtraData(outEntry.ExtraData);
            if (outEntry.LocalHeaderRequiresZip64)
            {
                data.StartNewEntry();
                data.AddLeLong(outEntry.Size);
                data.AddLeLong(outEntry.CompressedSize);
                data.AddNewEntry(1);
            }
            else
            {
                data.Delete(1);
            }
            outEntry.ExtraData = data.GetEntryData();
            WriteLEShort(buffer.Length);
            WriteLEShort(outEntry.ExtraData.Length);
            if (buffer.Length > 0)
            {
                baseStream_.Write(buffer, 0, buffer.Length);
            }
            if (outEntry.LocalHeaderRequiresZip64)
            {
                if (!data.Find(1))
                {
                    throw new ZipException("Internal error cannot find extra data");
                }
                update.SizePatchOffset = baseStream_.Position + data.CurrentReadIndex;
            }
            if (outEntry.ExtraData.Length > 0)
            {
                baseStream_.Write(outEntry.ExtraData, 0, outEntry.ExtraData.Length);
            }
        }
Exemple #5
0
 public void PutNextEntry(ZipEntry entry)
 {
     bool hasCrc;
     if (entry == null)
     {
         throw new ArgumentNullException("entry");
     }
     if (entries == null)
     {
         throw new InvalidOperationException("ZipOutputStream was finished");
     }
     if (curEntry != null)
     {
         CloseEntry();
     }
     if (entries.Count == 0x7fffffff)
     {
         throw new ZipException("Too many entries for Zip file");
     }
     CompressionMethod compressionMethod = entry.CompressionMethod;
     int compressionLevel = defaultCompressionLevel;
     entry.Flags &= 0x800;
     patchEntryHeader = false;
     if (entry.Size == 0L)
     {
         entry.CompressedSize = entry.Size;
         entry.Crc = 0L;
         compressionMethod = CompressionMethod.Stored;
         hasCrc = true;
     }
     else
     {
         hasCrc = (entry.Size >= 0L) && entry.HasCrc;
         if (compressionMethod == CompressionMethod.Stored)
         {
             if (!hasCrc)
             {
                 if (!CanPatchEntries)
                 {
                     compressionMethod = CompressionMethod.Deflated;
                     compressionLevel = 0;
                 }
             }
             else
             {
                 entry.CompressedSize = entry.Size;
                 hasCrc = entry.HasCrc;
             }
         }
     }
     if (!hasCrc)
     {
         if (!CanPatchEntries)
         {
             entry.Flags |= 8;
         }
         else
         {
             patchEntryHeader = true;
         }
     }
     if (Password != null)
     {
         entry.IsCrypted = true;
         if (entry.Crc < 0L)
         {
             entry.Flags |= 8;
         }
     }
     entry.Offset = offset;
     entry.CompressionMethod = compressionMethod;
     curMethod = compressionMethod;
     sizePatchPos = -1L;
     if ((useZip64_ == UseZip64.On) || ((entry.Size < 0L) && (useZip64_ == UseZip64.Dynamic)))
     {
         entry.ForceZip64();
     }
     WriteLeInt(0x4034b50);
     WriteLeShort(entry.Version);
     WriteLeShort(entry.Flags);
     WriteLeShort((byte)entry.CompressionMethodForHeader);
     WriteLeInt((int)entry.DosTime);
     if (hasCrc)
     {
         WriteLeInt((int)entry.Crc);
         if (entry.LocalHeaderRequiresZip64)
         {
             WriteLeInt(-1);
             WriteLeInt(-1);
         }
         else
         {
             WriteLeInt(entry.IsCrypted ? (((int)entry.CompressedSize) + 12) : ((int)entry.CompressedSize));
             WriteLeInt((int)entry.Size);
         }
     }
     else
     {
         if (patchEntryHeader)
         {
             crcPatchPos = baseOutputStream_.Position;
         }
         WriteLeInt(0);
         if (patchEntryHeader)
         {
             sizePatchPos = baseOutputStream_.Position;
         }
         if (entry.LocalHeaderRequiresZip64 || patchEntryHeader)
         {
             WriteLeInt(-1);
             WriteLeInt(-1);
         }
         else
         {
             WriteLeInt(0);
             WriteLeInt(0);
         }
     }
     byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
     if (buffer.Length > 0xffff)
     {
         throw new ZipException("Entry name too long.");
     }
     ZipExtraData extraData = new ZipExtraData(entry.ExtraData);
     if (entry.LocalHeaderRequiresZip64)
     {
         extraData.StartNewEntry();
         if (hasCrc)
         {
             extraData.AddLeLong(entry.Size);
             extraData.AddLeLong(entry.CompressedSize);
         }
         else
         {
             extraData.AddLeLong(-1L);
             extraData.AddLeLong(-1L);
         }
         extraData.AddNewEntry(1);
         if (!extraData.Find(1))
         {
             throw new ZipException("Internal error cant find extra data");
         }
         if (patchEntryHeader)
         {
             sizePatchPos = extraData.CurrentReadIndex;
         }
     }
     else
     {
         extraData.Delete(1);
     }
     if (entry.AESKeySize > 0)
     {
         AddExtraDataAES(entry, extraData);
     }
     byte[] entryData = extraData.GetEntryData();
     WriteLeShort(buffer.Length);
     WriteLeShort(entryData.Length);
     if (buffer.Length > 0)
     {
         baseOutputStream_.Write(buffer, 0, buffer.Length);
     }
     if (entry.LocalHeaderRequiresZip64 && patchEntryHeader)
     {
         sizePatchPos += baseOutputStream_.Position;
     }
     if (entryData.Length > 0)
     {
         baseOutputStream_.Write(entryData, 0, entryData.Length);
     }
     offset += (30 + buffer.Length) + entryData.Length;
     if (entry.AESKeySize > 0)
     {
         offset += entry.AESOverheadSize;
     }
     curEntry = entry;
     crc.Reset();
     if (compressionMethod == CompressionMethod.Deflated)
     {
         deflater_.Reset();
         deflater_.SetLevel(compressionLevel);
     }
     size = 0L;
     if (entry.IsCrypted)
     {
         if (entry.AESKeySize > 0)
         {
             WriteAESHeader(entry);
         }
         else if (entry.Crc < 0L)
         {
             WriteEncryptionHeader(entry.DosTime << 0x10);
         }
         else
         {
             WriteEncryptionHeader(entry.Crc);
         }
     }
 }