private void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) { CompressionMethod compressionMethod = entry.CompressionMethod; bool flag = true; bool flag2 = false; this.WriteLEInt(0x4034b50); this.WriteLEShort(entry.Version); this.WriteLEShort(entry.Flags); this.WriteLEShort((byte) compressionMethod); this.WriteLEInt((int) entry.DosTime); if (flag) { this.WriteLEInt((int) entry.Crc); if (entry.LocalHeaderRequiresZip64) { this.WriteLEInt(-1); this.WriteLEInt(-1); } else { this.WriteLEInt(entry.IsCrypted ? (((int) entry.CompressedSize) + 12) : ((int) entry.CompressedSize)); this.WriteLEInt((int) entry.Size); } } else { if (patchData != null) { patchData.CrcPatchOffset = this.stream_.Position; } this.WriteLEInt(0); if (patchData != null) { patchData.SizePatchOffset = this.stream_.Position; } if (entry.LocalHeaderRequiresZip64 && flag2) { this.WriteLEInt(-1); this.WriteLEInt(-1); } else { this.WriteLEInt(0); this.WriteLEInt(0); } } byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (buffer.Length > 0xffff) { throw new ZipException("Entry name too long."); } ZipExtraData data = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64 && (flag || flag2)) { data.StartNewEntry(); if (flag) { data.AddLeLong(entry.Size); data.AddLeLong(entry.CompressedSize); } else { data.AddLeLong(-1L); data.AddLeLong(-1L); } data.AddNewEntry(1); if (!data.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchData != null) { patchData.SizePatchOffset = data.CurrentReadIndex; } } else { data.Delete(1); } byte[] entryData = data.GetEntryData(); this.WriteLEShort(buffer.Length); this.WriteLEShort(entryData.Length); if (buffer.Length > 0) { this.stream_.Write(buffer, 0, buffer.Length); } if (entry.LocalHeaderRequiresZip64 && flag2) { patchData.SizePatchOffset += this.stream_.Position; } if (entryData.Length > 0) { this.stream_.Write(entryData, 0, entryData.Length); } }
internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if (extraData.Find(1)) { this.forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (this.size == 0xffffffffL)) { this.size = (ulong) extraData.ReadLong(); } if (localHeader || (this.compressedSize == 0xffffffffL)) { this.compressedSize = (ulong) extraData.ReadLong(); } if (!(localHeader || (this.offset != 0xffffffffL))) { this.offset = extraData.ReadLong(); } } else if (((this.versionToExtract & 0xff) >= 0x2d) && ((this.size == 0xffffffffL) || (this.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(); long num4 = extraData.ReadLong(); long num5 = extraData.ReadLong(); this.DateTime = System.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(); System.DateTime time = new System.DateTime(0x7b2, 1, 1, 0, 0, 0); this.DateTime = (time.ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime(); } } if (this.method == Maticsoft.ZipLib.Zip.CompressionMethod.WinZipAES) { this.ProcessAESExtraData(extraData); } }
private void ProcessAESExtraData(ZipExtraData extraData) { if (!extraData.Find(0x9901)) { throw new ZipException("AES Extra Data missing"); } this.versionToExtract = 0x33; this.Flags |= 0x40; int valueLength = extraData.ValueLength; if (valueLength < 7) { throw new ZipException("AES Extra Data Length " + valueLength + " invalid."); } int num2 = extraData.ReadShort(); int num3 = extraData.ReadShort(); int num4 = extraData.ReadByte(); int num5 = extraData.ReadShort(); this._aesVer = num2; this._aesEncryptionStrength = num4; this.method = (Maticsoft.ZipLib.Zip.CompressionMethod) num5; }
private void WriteLocalEntryHeader(ZipUpdate update) { ZipEntry outEntry = update.OutEntry; outEntry.Offset = this.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 (this.HaveKeys) { outEntry.IsCrypted = true; if (outEntry.Crc < 0L) { outEntry.Flags |= 8; } } else { outEntry.IsCrypted = false; } switch (this.useZip64_) { case Maticsoft.ZipLib.Zip.UseZip64.On: outEntry.ForceZip64(); break; case Maticsoft.ZipLib.Zip.UseZip64.Dynamic: if (outEntry.Size < 0L) { outEntry.ForceZip64(); } break; } } this.WriteLEInt(0x4034b50); this.WriteLEShort(outEntry.Version); this.WriteLEShort(outEntry.Flags); this.WriteLEShort((byte) outEntry.CompressionMethod); this.WriteLEInt((int) outEntry.DosTime); if (!outEntry.HasCrc) { update.CrcPatchOffset = this.baseStream_.Position; this.WriteLEInt(0); } else { this.WriteLEInt((int) outEntry.Crc); } if (outEntry.LocalHeaderRequiresZip64) { this.WriteLEInt(-1); this.WriteLEInt(-1); } else { if ((outEntry.CompressedSize < 0L) || (outEntry.Size < 0L)) { update.SizePatchOffset = this.baseStream_.Position; } this.WriteLEInt((int) outEntry.CompressedSize); this.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(); this.WriteLEShort(buffer.Length); this.WriteLEShort(outEntry.ExtraData.Length); if (buffer.Length > 0) { this.baseStream_.Write(buffer, 0, buffer.Length); } if (outEntry.LocalHeaderRequiresZip64) { if (!data.Find(1)) { throw new ZipException("Internal error cannot find extra data"); } update.SizePatchOffset = this.baseStream_.Position + data.CurrentReadIndex; } if (outEntry.ExtraData.Length > 0) { this.baseStream_.Write(outEntry.ExtraData, 0, outEntry.ExtraData.Length); } }
private int WriteCentralDirectoryHeader(ZipEntry entry) { if (entry.CompressedSize < 0L) { throw new ZipException("Attempt to write central directory entry with unknown csize"); } if (entry.Size < 0L) { throw new ZipException("Attempt to write central directory entry with unknown size"); } if (entry.Crc < 0L) { throw new ZipException("Attempt to write central directory entry with unknown crc"); } this.WriteLEInt(0x2014b50); this.WriteLEShort(0x33); this.WriteLEShort(entry.Version); this.WriteLEShort(entry.Flags); this.WriteLEShort((byte) entry.CompressionMethod); this.WriteLEInt((int) entry.DosTime); this.WriteLEInt((int) entry.Crc); if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL)) { this.WriteLEInt(-1); } else { this.WriteLEInt((int) (((ulong) entry.CompressedSize) & 0xffffffffL)); } if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL)) { this.WriteLEInt(-1); } else { this.WriteLEInt((int) entry.Size); } byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (buffer.Length > 0xffff) { throw new ZipException("Entry name is too long."); } this.WriteLEShort(buffer.Length); ZipExtraData data = new ZipExtraData(entry.ExtraData); if (entry.CentralHeaderRequiresZip64) { data.StartNewEntry(); if ((entry.Size >= 0xffffffffL) || (this.useZip64_ == Maticsoft.ZipLib.Zip.UseZip64.On)) { data.AddLeLong(entry.Size); } if ((entry.CompressedSize >= 0xffffffffL) || (this.useZip64_ == Maticsoft.ZipLib.Zip.UseZip64.On)) { data.AddLeLong(entry.CompressedSize); } if (entry.Offset >= 0xffffffffL) { data.AddLeLong(entry.Offset); } data.AddNewEntry(1); } else { data.Delete(1); } byte[] entryData = data.GetEntryData(); this.WriteLEShort(entryData.Length); this.WriteLEShort((entry.Comment != null) ? entry.Comment.Length : 0); this.WriteLEShort(0); this.WriteLEShort(0); if (entry.ExternalFileAttributes != -1) { this.WriteLEInt(entry.ExternalFileAttributes); } else if (entry.IsDirectory) { this.WriteLEUint(0x10); } else { this.WriteLEUint(0); } if (entry.Offset >= 0xffffffffL) { this.WriteLEUint(uint.MaxValue); } else { this.WriteLEUint((uint) ((int) entry.Offset)); } if (buffer.Length > 0) { this.baseStream_.Write(buffer, 0, buffer.Length); } if (entryData.Length > 0) { this.baseStream_.Write(entryData, 0, entryData.Length); } byte[] buffer3 = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0]; if (buffer3.Length > 0) { this.baseStream_.Write(buffer3, 0, buffer3.Length); } return (((0x2e + buffer.Length) + entryData.Length) + buffer3.Length); }
private long TestLocalHeader(ZipEntry entry, HeaderTest tests) { lock (this.baseStream_) { bool flag = (tests & HeaderTest.Header) != 0; bool flag2 = (tests & HeaderTest.Extract) != 0; this.baseStream_.Seek(this.offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin); if (this.ReadLEUint() != 0x4034b50) { throw new ZipException(string.Format("Wrong local header signature @{0:X}", this.offsetOfFirstEntry + entry.Offset)); } short num = (short) this.ReadLEUshort(); short flags = (short) this.ReadLEUshort(); short num3 = (short) this.ReadLEUshort(); short num4 = (short) this.ReadLEUshort(); short num5 = (short) this.ReadLEUshort(); uint num6 = this.ReadLEUint(); long num7 = this.ReadLEUint(); long num8 = this.ReadLEUint(); int num9 = this.ReadLEUshort(); int num10 = this.ReadLEUshort(); byte[] buffer = new byte[num9]; StreamUtils.ReadFully(this.baseStream_, buffer); byte[] buffer2 = new byte[num10]; StreamUtils.ReadFully(this.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 (((this.offsetOfFirstEntry + entry.Offset) + 30L) + num11); } }