internal void ProcessExtraData(bool localHeader) { ZipExtraData zipExtraData = new ZipExtraData(this.extra); if (zipExtraData.Find(1)) { this.forceZip64_ = true; if (zipExtraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (this.size == (ulong)-1) { this.size = (ulong)zipExtraData.ReadLong(); } if (this.compressedSize == (ulong)-1) { this.compressedSize = (ulong)zipExtraData.ReadLong(); } if (!localHeader && this.offset == (long)((ulong)-1)) { this.offset = zipExtraData.ReadLong(); } } else if ((this.versionToExtract & 255) >= 45 && (this.size == (ulong)-1 || this.compressedSize == (ulong)-1)) { throw new ZipException("Zip64 Extended information required but is missing."); } this.DateTime = this.GetDateTime(zipExtraData); if (this.method == CompressionMethod.WinZipAES) { this.ProcessAESExtraData(zipExtraData); } }
internal void ProcessExtraData(bool localHeader) { ZipExtraData zipExtraData = new ZipExtraData(extra); if (zipExtraData.Find(1)) { forceZip64_ = true; if (zipExtraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (size == uint.MaxValue) { size = (ulong)zipExtraData.ReadLong(); } if (compressedSize == uint.MaxValue) { compressedSize = (ulong)zipExtraData.ReadLong(); } if (!localHeader && offset == uint.MaxValue) { offset = zipExtraData.ReadLong(); } } else if ((versionToExtract & 0xFF) >= 45 && (size == uint.MaxValue || compressedSize == uint.MaxValue)) { throw new ZipException("Zip64 Extended information required but is missing."); } DateTime = GetDateTime(zipExtraData); if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(zipExtraData); } }
// For AES the method in the entry is 99, and the real compression method is in the extradata // private void ProcessAESExtraData(ZipExtraData extraData) { if (extraData.Find(0x9901)) { // Set version and flag for Zipfile.CreateAndInitDecryptionStream versionToExtract = ZipConstants.VERSION_AES; // Ver 5.1 = AES see "Version" getter // Set StrongEncryption flag for ZipFile.CreateAndInitDecryptionStream Flags = Flags | (int)GeneralBitFlags.StrongEncryption; // // Unpack AES extra data field see http://www.winzip.com/aes_info.htm int length = extraData.ValueLength; // Data size currently 7 if (length < 7) { throw new ZipException("AES Extra Data Length " + length + " invalid."); } int ver = extraData.ReadShort(); // Version number (1=AE-1 2=AE-2) int vendorId = extraData.ReadShort(); // 2-character vendor ID 0x4541 = "AE" int encrStrength = extraData.ReadByte(); // encryption strength 1 = 128 2 = 192 3 = 256 int actualCompress = extraData.ReadShort(); // The actual compression method used to compress the file _aesVer = ver; _aesEncryptionStrength = encrStrength; method = (CompressionMethod)actualCompress; } else { throw new ZipException("AES Extra Data missing"); } }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if (extraData.Find(0x0001)) { // Version required to extract is ignored here as some archivers dont set it correctly // in theory it should be version 45 or higher // The recorded size will change but remember that this is zip64. forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (size == uint.MaxValue)) { size = (ulong)extraData.ReadLong(); } if (localHeader || (compressedSize == uint.MaxValue)) { compressedSize = (ulong)extraData.ReadLong(); } if (!localHeader && (offset == uint.MaxValue)) { offset = extraData.ReadLong(); } // Disk number on which file starts is ignored } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } dateTime = GetDateTime(extraData); if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(extraData); } }
private void ProcessAESExtraData(ZipExtraData extraData) { if (!extraData.Find(39169)) { throw new Exception("AES Extra Data missing"); } this.versionToExtract = 51; this.Flags |= 64; int valueLength = extraData.ValueLength; if (valueLength < 7) { throw new Exception("AES Extra Data Length " + valueLength + " invalid."); } extraData.ReadShort(); extraData.ReadShort(); extraData.ReadByte(); int num = extraData.ReadShort(); this.method = (CompressionMethod)num; }
private void ProcessAESExtraData(ZipExtraData extraData) { if (extraData.Find(39169)) { versionToExtract = 51; Flags |= 64; int valueLength = extraData.ValueLength; if (valueLength < 7) { throw new ZipException("AES Extra Data Length " + valueLength + " invalid."); } int aesVer = extraData.ReadShort(); extraData.ReadShort(); int aesEncryptionStrength = extraData.ReadByte(); int num = extraData.ReadShort(); _aesVer = aesVer; _aesEncryptionStrength = aesEncryptionStrength; method = (CompressionMethod)num; return; } throw new ZipException("AES Extra Data missing"); }
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 = (ICSharpCode.SharpZipLib.Zip.CompressionMethod)num5; }
internal void ProcessExtraData(bool localHeader) { ZipExtraData zipExtraData = new ZipExtraData(this.extra); if (zipExtraData.Find(1)) { this.forceZip64_ = true; if (zipExtraData.ValueLength < 4) { throw new Exception("Extra data extended Zip64 information length is invalid"); } if (localHeader || this.size == (ulong)-1) { this.size = (ulong)zipExtraData.ReadLong(); } if (localHeader || this.compressedSize == (ulong)-1) { this.compressedSize = (ulong)zipExtraData.ReadLong(); } if (!localHeader && this.offset == (long)((ulong)-1)) { this.offset = zipExtraData.ReadLong(); } } else if ((this.versionToExtract & 255) >= 45 && (this.size == (ulong)-1 || this.compressedSize == (ulong)-1)) { throw new Exception("Zip64 Extended information required but is missing."); } if (zipExtraData.Find(10)) { if (zipExtraData.ValueLength < 4) { throw new Exception("NTFS Extra data invalid"); } zipExtraData.ReadInt(); while (zipExtraData.UnreadCount >= 4) { int num = zipExtraData.ReadShort(); int num2 = zipExtraData.ReadShort(); if (num == 1) { if (num2 >= 24) { long fileTime = zipExtraData.ReadLong(); zipExtraData.ReadLong(); zipExtraData.ReadLong(); this.DateTime = DateTime.FromFileTime(fileTime); } break; } zipExtraData.Skip(num2); } } else if (zipExtraData.Find(21589)) { int valueLength = zipExtraData.ValueLength; int num3 = zipExtraData.ReadByte(); if ((num3 & 1) != 0 && valueLength >= 5) { int seconds = zipExtraData.ReadInt(); DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0); this.DateTime = (dateTime.ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime(); } } if (this.method == CompressionMethod.WinZipAES) { this.ProcessAESExtraData(zipExtraData); } }
// Write the local file header // TODO: ZipHelperStream.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) { CompressionMethod method = entry.CompressionMethod; bool headerInfoAvailable = true; // How to get this? bool patchEntryHeader = false; WriteLEInt(ZipConstants.LocalHeaderSignature); WriteLEShort(entry.Version); WriteLEShort(entry.Flags); WriteLEShort((byte)method); WriteLEInt((int)entry.DosTime); if (headerInfoAvailable) { WriteLEInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLEInt(-1); WriteLEInt(-1); } else { WriteLEInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLEInt((int)entry.Size); } } else { if (patchData != null) { patchData.CrcPatchOffset = stream_.Position; } WriteLEInt(0); // Crc if (patchData != null) { patchData.SizePatchOffset = stream_.Position; } // For local header both sizes appear in Zip64 Extended Information if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { WriteLEInt(-1); WriteLEInt(-1); } else { WriteLEInt(0); // Compressed size WriteLEInt(0); // Uncompressed size } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64 && (headerInfoAvailable || patchEntryHeader)) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchData != null) { patchData.SizePatchOffset = ed.CurrentReadIndex; } } else { ed.Delete(1); } byte[] extra = ed.GetEntryData(); WriteLEShort(name.Length); WriteLEShort(extra.Length); if (name.Length > 0) { stream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { patchData.SizePatchOffset += stream_.Position; } if (extra.Length > 0) { stream_.Write(extra, 0, extra.Length); } }
public void UnreadCountValid() { ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 }); Assert.AreEqual(4, zed.Length, "Length should be 4"); Assert.IsTrue(zed.Find(1), "Should find tag 1"); Assert.AreEqual(0, zed.UnreadCount); // seven bytes zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); for (int i = 0; i < 7; ++i) { Assert.AreEqual(7 - i, zed.UnreadCount); zed.ReadByte(); } zed.ReadByte(); Assert.AreEqual(0, zed.UnreadCount); }
public void ReadOverrunShort() { ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 }); Assert.AreEqual(4, zed.Length, "Length should be 4"); Assert.IsTrue(zed.Find(1), "Should find tag 1"); // Empty Tag bool exceptionCaught = false; try { zed.ReadShort(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); // Single byte zed = new ZipExtraData(new byte[] { 1, 0, 1, 0, 1 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; try { zed.ReadShort(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); zed = new ZipExtraData(new byte[] { 1, 0, 2, 0, 1, 2 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); zed.ReadShort(); exceptionCaught = false; try { zed.ReadShort(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); }
public void BasicOperations() { ZipExtraData zed = new ZipExtraData(null); Assert.AreEqual(0, zed.Length); zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 }); Assert.AreEqual(4, zed.Length, "A length should be 4"); ZipExtraData zed2 = new ZipExtraData(); Assert.AreEqual(0, zed2.Length); zed2.AddEntry(1, new byte[] { }); byte[] data = zed.GetEntryData(); for (int i = 0; i < data.Length; ++i) { Assert.AreEqual(zed2.GetEntryData()[i], data[i]); } Assert.AreEqual(4, zed2.Length, "A1 length should be 4"); bool findResult = zed.Find(2); Assert.IsFalse(findResult, "A - Shouldnt find tag 2"); findResult = zed.Find(1); Assert.IsTrue(findResult, "A - Should find tag 1"); Assert.AreEqual(0, zed.ValueLength, "A- Length of entry should be 0"); Assert.AreEqual(-1, zed.ReadByte()); Assert.AreEqual(0, zed.GetStreamForTag(1).Length, "A - Length of stream should be 0"); zed = new ZipExtraData(new byte[] { 1, 0, 3, 0, 1, 2, 3 }); Assert.AreEqual(7, zed.Length, "Expected a length of 7"); findResult = zed.Find(1); Assert.IsTrue(findResult, "B - Should find tag 1"); Assert.AreEqual(3, zed.ValueLength, "B - Length of entry should be 3"); for (int i = 1; i <= 3; ++i) { Assert.AreEqual(i, zed.ReadByte()); } Assert.AreEqual(-1, zed.ReadByte()); Stream s = zed.GetStreamForTag(1); Assert.AreEqual(3, s.Length, "B.1 Stream length should be 3"); for (int i = 1; i <= 3; ++i) { Assert.AreEqual(i, s.ReadByte()); } Assert.AreEqual(-1, s.ReadByte()); zed = new ZipExtraData(new byte[] { 1, 0, 3, 0, 1, 2, 3, 2, 0, 1, 0, 56 }); Assert.AreEqual(12, zed.Length, "Expected a length of 12"); findResult = zed.Find(1); Assert.IsTrue(findResult, "C.1 - Should find tag 1"); Assert.AreEqual(3, zed.ValueLength, "C.1 - Length of entry should be 3"); for (int i = 1; i <= 3; ++i) { Assert.AreEqual(i, zed.ReadByte()); } Assert.AreEqual(-1, zed.ReadByte()); findResult = zed.Find(2); Assert.IsTrue(findResult, "C.2 - Should find tag 2"); Assert.AreEqual(1, zed.ValueLength, "C.2 - Length of entry should be 1"); Assert.AreEqual(56, zed.ReadByte()); Assert.AreEqual(-1, zed.ReadByte()); s = zed.GetStreamForTag(2); Assert.AreEqual(1, s.Length); Assert.AreEqual(56, s.ReadByte()); Assert.AreEqual(-1, s.ReadByte()); zed = new ZipExtraData(); zed.AddEntry(7, new byte[] { 33, 44, 55 }); findResult = zed.Find(7); Assert.IsTrue(findResult, "Add.1 should find new tag"); Assert.AreEqual(3, zed.ValueLength, "Add.1 length should be 3"); Assert.AreEqual(33, zed.ReadByte()); Assert.AreEqual(44, zed.ReadByte()); Assert.AreEqual(55, zed.ReadByte()); Assert.AreEqual(-1, zed.ReadByte()); zed.AddEntry(7, null); findResult = zed.Find(7); Assert.IsTrue(findResult, "Add.2 should find new tag"); Assert.AreEqual(0, zed.ValueLength, "Add.2 length should be 0"); zed.StartNewEntry(); zed.AddData(0xae); zed.AddNewEntry(55); findResult = zed.Find(55); Assert.IsTrue(findResult, "Add.3 should find new tag"); Assert.AreEqual(1, zed.ValueLength, "Add.3 length should be 1"); Assert.AreEqual(0xae, zed.ReadByte()); Assert.AreEqual(-1, zed.ReadByte()); zed = new ZipExtraData(); zed.StartNewEntry(); zed.AddLeLong(0); zed.AddLeLong(-4); zed.AddLeLong(-1); zed.AddLeLong(long.MaxValue); zed.AddLeLong(long.MinValue); zed.AddLeLong(0x123456789ABCDEF0); zed.AddLeLong(unchecked((long)0xFEDCBA9876543210)); zed.AddNewEntry(567); s = zed.GetStreamForTag(567); long longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(0, longValue, "Expected long value of zero"); longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(-4, longValue, "Expected long value of -4"); longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(-1, longValue, "Expected long value of -1"); longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(long.MaxValue, longValue, "Expected long value of MaxValue"); longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(long.MinValue, longValue, "Expected long value of MinValue"); longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(0x123456789abcdef0, longValue, "Expected long value of MinValue"); longValue = ReadLong(s); Assert.AreEqual(longValue, zed.ReadLong(), "Read/stream mismatch"); Assert.AreEqual(unchecked((long)0xFEDCBA9876543210), longValue, "Expected long value of MinValue"); }
internal void ProcessExtraData(bool localHeader) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) ZipExtraData zipExtraData = new ZipExtraData(extra); if (zipExtraData.Find(1)) { forceZip64_ = true; if (zipExtraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || size == 4294967295u) { size = (ulong)zipExtraData.ReadLong(); } if (localHeader || compressedSize == 4294967295u) { compressedSize = (ulong)zipExtraData.ReadLong(); } if (!localHeader && offset == 4294967295u) { offset = zipExtraData.ReadLong(); } } else if ((versionToExtract & 0xFF) >= 45 && (size == 4294967295u || compressedSize == 4294967295u)) { throw new ZipException("Zip64 Extended information required but is missing."); } if (zipExtraData.Find(10)) { if (zipExtraData.ValueLength < 4) { throw new ZipException("NTFS Extra data invalid"); } zipExtraData.ReadInt(); while (zipExtraData.UnreadCount >= 4) { int num = zipExtraData.ReadShort(); int num2 = zipExtraData.ReadShort(); if (num == 1) { if (num2 >= 24) { long num3 = zipExtraData.ReadLong(); zipExtraData.ReadLong(); zipExtraData.ReadLong(); DateTime = global::System.DateTime.FromFileTime(num3); } break; } zipExtraData.Skip(num2); } } else if (zipExtraData.Find(21589)) { int valueLength = zipExtraData.ValueLength; int num4 = zipExtraData.ReadByte(); if (((uint)num4 & (true ? 1u : 0u)) != 0 && valueLength >= 5) { int num5 = zipExtraData.ReadInt(); DateTime = (new global::System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, num5, 0)).ToLocalTime(); } } if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(zipExtraData); } }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { var extraData = new ZipExtraData(this.extra); if (extraData.Find(0x0001)) { // Version required to extract is ignored here as some archivers dont set it correctly // in theory it should be version 45 or higher // The recorded size will change but remember that this is zip64. forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } // (localHeader ||) was deleted, because actually there is no specific difference with reading sizes between local header & central directory // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT // ... // 4.4 Explanation of fields // ... // 4.4.8 compressed size: (4 bytes) // 4.4.9 uncompressed size: (4 bytes) // // The size of the file compressed (4.4.8) and uncompressed, // (4.4.9) respectively. When a decryption header is present it // will be placed in front of the file data and the value of the // compressed file size will include the bytes of the decryption // header. If bit 3 of the general purpose bit flag is set, // these fields are set to zero in the local header and the // correct values are put in the data descriptor and // in the central directory. If an archive is in ZIP64 format // and the value in this field is 0xFFFFFFFF, the size will be // in the corresponding 8 byte ZIP64 extended information // extra field. When encrypting the central directory, if the // local header is not in ZIP64 format and general purpose bit // flag 13 is set indicating masking, the value stored for the // uncompressed size in the Local Header will be zero. // // Othewise there is problem with minizip implementation if (size == uint.MaxValue) { size = (ulong)extraData.ReadLong(); } if (compressedSize == uint.MaxValue) { compressedSize = (ulong)extraData.ReadLong(); } if (!localHeader && (offset == uint.MaxValue)) { offset = extraData.ReadLong(); } // Disk number on which file starts is ignored } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } DateTime = GetDateTime(extraData); if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(extraData); } }
private void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) { CompressionMethod compressionMethod = entry.CompressionMethod; bool flag = true; bool flag2 = false; this.WriteLEInt(67324752); this.WriteLEShort(entry.Version); this.WriteLEShort(entry.Flags); this.WriteLEShort((int)((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) : ((int)entry.CompressedSize + 12)); 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[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (array.Length > 65535) { throw new Exception("Entry name too long."); } ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64 && (flag || flag2)) { zipExtraData.StartNewEntry(); if (flag) { zipExtraData.AddLeLong(entry.Size); zipExtraData.AddLeLong(entry.CompressedSize); } else { zipExtraData.AddLeLong(-1L); zipExtraData.AddLeLong(-1L); } zipExtraData.AddNewEntry(1); if (!zipExtraData.Find(1)) { throw new Exception("Internal error cant find extra data"); } if (patchData != null) { patchData.SizePatchOffset = (long)zipExtraData.CurrentReadIndex; } } else { zipExtraData.Delete(1); } byte[] entryData = zipExtraData.GetEntryData(); this.WriteLEShort(array.Length); this.WriteLEShort(entryData.Length); if (array.Length > 0) { this.stream_.Write(array, 0, array.Length); } if (entry.LocalHeaderRequiresZip64 && flag2) { patchData.SizePatchOffset += this.stream_.Position; } if (entryData.Length > 0) { this.stream_.Write(entryData, 0, entryData.Length); } }
public void ReadOverrunInt() { var zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 }); Assert.AreEqual(4, zed.Length, "Length should be 4"); Assert.IsTrue(zed.Find(1), "Should find tag 1"); // Empty Tag bool exceptionCaught = false; try { zed.ReadInt(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); // three bytes zed = new ZipExtraData(new byte[] { 1, 0, 3, 0, 1, 2, 3 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; try { zed.ReadInt(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); zed.ReadInt(); exceptionCaught = false; try { zed.ReadInt(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); }
/// <summary> /// Test a local header against that provided from the central directory /// </summary> /// <param name="entry"> /// The entry to test against /// </param> /// <param name="tests">The type of <see cref="HeaderTest">tests</see> to carry out.</param> /// <returns>The offset of the entries data in the file</returns> long TestLocalHeader(ZipEntry entry, HeaderTest tests) { lock(baseStream_) { bool testHeader = (tests & HeaderTest.Header) != 0; bool testData = (tests & HeaderTest.Extract) != 0; baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin); if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) { throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset)); } short extractVersion = ( short )ReadLEUshort(); short localFlags = ( short )ReadLEUshort(); short compressionMethod = ( short )ReadLEUshort(); short fileTime = ( short )ReadLEUshort(); short fileDate = ( short )ReadLEUshort(); uint crcValue = ReadLEUint(); long size = ReadLEUint(); long compressedSize = ReadLEUint(); int storedNameLength = ReadLEUshort(); int extraDataLength = ReadLEUshort(); if ( testData ) { if ( entry.IsFile ) { if ( !entry.IsCompressionMethodSupported() ) { throw new ZipException("Compression method not supported"); } if ( (extractVersion > ZipConstants.VersionMadeBy) || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64)) ) { throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion)); } if ( (localFlags & ( int )(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0 ) { throw new ZipException("The library does not support the zip version required to extract this entry"); } } } if ( testHeader ) { if ((extractVersion <= 63) && // Ignore later versions as we dont know about them.. (extractVersion != 10) && (extractVersion != 11) && (extractVersion != 20) && (extractVersion != 21) && (extractVersion != 25) && (extractVersion != 27) && (extractVersion != 45) && (extractVersion != 46) && (extractVersion != 50) && (extractVersion != 51) && (extractVersion != 52) && (extractVersion != 61) && (extractVersion != 62) && (extractVersion != 63) ) { throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion)); } // Local entry flags dont have reserved bit set on. if ( (localFlags & ( int )(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0 ) { throw new ZipException("Reserved bit flags cannot be set."); } // Encryption requires extract version >= 20 if ( ((localFlags & ( int )GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20) ) { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } // Strong encryption requires encryption flag to be set and extract version >= 50. if ( (localFlags & (int)GeneralBitFlags.StrongEncryption) != 0 ) { if ( (localFlags & (int)GeneralBitFlags.Encrypted) == 0 ) { throw new ZipException("Strong encryption flag set but encryption flag is not set"); } if ( extractVersion < 50 ) { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } } // Patched entries require extract version >= 27 if ( ((localFlags & ( int )GeneralBitFlags.Patched) != 0) && (extractVersion < 27) ) { throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion)); } // Central header flags match local entry flags. if ( localFlags != entry.Flags ) { throw new ZipException("Central header/local header flags mismatch"); } // Central header compression method matches local entry if ( entry.CompressionMethod != ( CompressionMethod )compressionMethod ) { throw new ZipException("Central header/local header compression method mismatch"); } // Strong encryption and extract version match if ( (localFlags & ( int )GeneralBitFlags.StrongEncryption) != 0 ) { if ( extractVersion < 62 ) { throw new ZipException("Strong encryption flag set but version not high enough"); } } if ( (localFlags & ( int )GeneralBitFlags.HeaderMasked) != 0 ) { if ( (fileTime != 0) || (fileDate != 0) ) { throw new ZipException("Header masked set but date/time values non-zero"); } } if ( (localFlags & ( int )GeneralBitFlags.Descriptor) == 0 ) { if ( crcValue != (uint)entry.Crc ) { throw new ZipException("Central header/local header crc mismatch"); } } // Crc valid for empty entry. if ( (size == 0) && (compressedSize == 0) ) { if ( crcValue != 0 ) { throw new ZipException("Invalid CRC for empty entry"); } } // TODO: make test more correct... can't compare lengths as was done originally as this can fail for MBCS strings // Assuming a code page at this point is not valid? Best is to store the name length in the ZipEntry probably if ( entry.Name.Length > storedNameLength ) { throw new ZipException("File name length mismatch"); } byte[] nameData = new byte[storedNameLength]; StreamUtils.ReadFully(baseStream_, nameData); string localName = ZipConstants.ConvertToStringExt(localFlags, nameData); // Central directory and local entry name match if ( localName != entry.Name ) { throw new ZipException("Central header and local header file name mismatch"); } // Directories have zero size. if ( entry.IsDirectory ) { if ( (compressedSize != 0) || (size != 0) ) { throw new ZipException("Directory cannot have size"); } } if ( !ZipNameTransform.IsValidName(localName, true) ) { throw new ZipException("Name is invalid"); } byte[] data = new byte[extraDataLength]; StreamUtils.ReadFully(baseStream_, data); ZipExtraData ed = new ZipExtraData(data); // Extra data / zip64 checks if ( ed.Find(1) ) { // Zip64 extra data but 'extract version' is too low if ( extractVersion < ZipConstants.VersionZip64 ) { throw new ZipException( string.Format("Extra data contains Zip64 information but version {0}.{1} is not high enough", extractVersion / 10, extractVersion % 10)); } // Zip64 extra data but size fields dont indicate its required. if ( (( uint )size != uint.MaxValue) && (( uint )compressedSize != uint.MaxValue) ) { throw new ZipException("Entry sizes not correct for Zip64"); } size = ed.ReadLong(); compressedSize = ed.ReadLong(); } else { // No zip64 extra data but entry requires it. if ( (extractVersion >= ZipConstants.VersionZip64) && ((( uint )size == uint.MaxValue) || (( uint )compressedSize == uint.MaxValue)) ) { throw new ZipException("Required Zip64 extended information missing"); } } } int extraLength = storedNameLength + extraDataLength; return offsetOfFirstEntry + entry.Offset + ZipConstants.LocalHeaderBaseSize + extraLength; } }
void WriteLocalEntryHeader(ZipUpdate update) { ZipEntry entry = update.OutEntry; entry.Offset = baseStream_.Position; if (update.Command != UpdateCommand.Copy) { if (entry.CompressionMethod == CompressionMethod.Deflated) { if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; entry.CompressionMethod = CompressionMethod.Stored; } } else if (entry.CompressionMethod == CompressionMethod.Stored) { entry.Flags &= ~(int)GeneralBitFlags.Descriptor; } if (HaveKeys) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= (int)GeneralBitFlags.Descriptor; } } else { entry.IsCrypted = false; } switch (useZip64_) { case UseZip64.Dynamic: if (entry.Size < 0) { entry.ForceZip64(); } break; case UseZip64.On: entry.ForceZip64(); break; case UseZip64.Off: break; } } WriteLEInt(ZipConstants.LocalHeaderSignature); WriteLEShort(entry.Version); WriteLEShort(entry.Flags); WriteLEShort((byte)entry.CompressionMethod); WriteLEInt(( int )entry.DosTime); if ( !entry.HasCrc ) { update.CrcPatchOffset = baseStream_.Position; WriteLEInt(( int )0); } else { WriteLEInt(unchecked(( int )entry.Crc)); } if (entry.LocalHeaderRequiresZip64) { WriteLEInt(-1); WriteLEInt(-1); } else { if ( (entry.CompressedSize < 0) || (entry.Size < 0) ) { update.SizePatchOffset = baseStream_.Position; } WriteLEInt(( int )entry.CompressedSize); WriteLEInt(( int )entry.Size); } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if ( name.Length > 0xFFFF ) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if ( entry.LocalHeaderRequiresZip64 ) { ed.StartNewEntry(); ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); ed.AddNewEntry(1); } else { ed.Delete(1); } entry.ExtraData = ed.GetEntryData(); WriteLEShort(name.Length); WriteLEShort(entry.ExtraData.Length); if ( name.Length > 0 ) { baseStream_.Write(name, 0, name.Length); } if ( entry.LocalHeaderRequiresZip64 ) { if ( !ed.Find(1) ) { throw new ZipException("Internal error cannot find extra data"); } update.SizePatchOffset = baseStream_.Position + ed.CurrentReadIndex; } if ( entry.ExtraData.Length > 0 ) { baseStream_.Write(entry.ExtraData, 0, entry.ExtraData.Length); } }
long TestLocalHeader(ZipEntry entry, HeaderTest tests) { lock(baseStream_) { bool testHeader = (tests & HeaderTest.Header) != 0; bool testData = (tests & HeaderTest.Extract) != 0; baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin); if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) { throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset)); } short extractVersion = ( short )ReadLEUshort(); short localFlags = ( short )ReadLEUshort(); short compressionMethod = ( short )ReadLEUshort(); short fileTime = ( short )ReadLEUshort(); short fileDate = ( short )ReadLEUshort(); uint crcValue = ReadLEUint(); long compressedSize = ReadLEUint(); long size = ReadLEUint(); int storedNameLength = ReadLEUshort(); int extraDataLength = ReadLEUshort(); byte[] nameData = new byte[storedNameLength]; StreamUtils.ReadFully(baseStream_, nameData); byte[] extraData = new byte[extraDataLength]; StreamUtils.ReadFully(baseStream_, extraData); ZipExtraData localExtraData = new ZipExtraData(extraData); if (localExtraData.Find(1)) { if (extractVersion < ZipConstants.VersionZip64) { throw new ZipException( string.Format("Extra data contains Zip64 information but version {0}.{1} is not high enough", extractVersion / 10, extractVersion % 10)); } if (((uint)size != uint.MaxValue) && ((uint)compressedSize != uint.MaxValue)) { throw new ZipException("Entry sizes not correct for Zip64"); } size = localExtraData.ReadLong(); compressedSize = localExtraData.ReadLong(); if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0) { if ( (size != -1) && (size != entry.Size)) { throw new ZipException("Size invalid for descriptor"); } if ((compressedSize != -1) && (compressedSize != entry.CompressedSize)) { throw new ZipException("Compressed size invalid for descriptor"); } } } else { if ((extractVersion >= ZipConstants.VersionZip64) && (((uint)size == uint.MaxValue) || ((uint)compressedSize == uint.MaxValue))) { throw new ZipException("Required Zip64 extended information missing"); } } if ( testData ) { if ( entry.IsFile ) { if ( !entry.IsCompressionMethodSupported() ) { throw new ZipException("Compression method not supported"); } if ( (extractVersion > ZipConstants.VersionMadeBy) || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64)) ) { throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion)); } if ( (localFlags & ( int )(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0 ) { throw new ZipException("The library does not support the zip version required to extract this entry"); } } } if (testHeader) { if ((extractVersion <= 63) && (extractVersion != 10) && (extractVersion != 11) && (extractVersion != 20) && (extractVersion != 21) && (extractVersion != 25) && (extractVersion != 27) && (extractVersion != 45) && (extractVersion != 46) && (extractVersion != 50) && (extractVersion != 51) && (extractVersion != 52) && (extractVersion != 61) && (extractVersion != 62) && (extractVersion != 63) ) { throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion)); } if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0) { throw new ZipException("Reserved bit flags cannot be set."); } if (((localFlags & (int)GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20)) { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) { if ((localFlags & (int)GeneralBitFlags.Encrypted) == 0) { throw new ZipException("Strong encryption flag set but encryption flag is not set"); } if (extractVersion < 50) { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } } if (((localFlags & (int)GeneralBitFlags.Patched) != 0) && (extractVersion < 27)) { throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion)); } if (localFlags != entry.Flags) { throw new ZipException("Central header/local header flags mismatch"); } if (entry.CompressionMethod != (CompressionMethod)compressionMethod) { throw new ZipException("Central header/local header compression method mismatch"); } if (entry.Version != extractVersion) { throw new ZipException("Extract version mismatch"); } if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) { if (extractVersion < 62) { throw new ZipException("Strong encryption flag set but version not high enough"); } } if ((localFlags & (int)GeneralBitFlags.HeaderMasked) != 0) { if ((fileTime != 0) || (fileDate != 0)) { throw new ZipException("Header masked set but date/time values non-zero"); } } if ((localFlags & (int)GeneralBitFlags.Descriptor) == 0) { if (crcValue != (uint)entry.Crc) { throw new ZipException("Central header/local header crc mismatch"); } } if ((size == 0) && (compressedSize == 0)) { if (crcValue != 0) { throw new ZipException("Invalid CRC for empty entry"); } } if (entry.Name.Length > storedNameLength) { throw new ZipException("File name length mismatch"); } string localName = ZipConstants.ConvertToStringExt(localFlags, nameData); if (localName != entry.Name) { throw new ZipException("Central header and local header file name mismatch"); } if (entry.IsDirectory) { if (size > 0) { throw new ZipException("Directory cannot have size"); } if (entry.IsCrypted) { if (compressedSize > ZipConstants.CryptoHeaderSize + 2) { throw new ZipException("Directory compressed size invalid"); } } else if (compressedSize > 2) { throw new ZipException("Directory compressed size invalid"); } } if (!ZipNameTransform.IsValidName(localName, true)) { throw new ZipException("Name is invalid"); } } if (((localFlags & (int)GeneralBitFlags.Descriptor) == 0) || ((size > 0) || (compressedSize > 0))) { if (size != entry.Size) { throw new ZipException( string.Format("Size mismatch between central header({0}) and local header({1})", entry.Size, size)); } if (compressedSize != entry.CompressedSize) { throw new ZipException( string.Format("Compressed size mismatch between central header({0}) and local header({1})", entry.CompressedSize, compressedSize)); } } int extraLength = storedNameLength + extraDataLength; return offsetOfFirstEntry + entry.Offset + ZipConstants.LocalHeaderBaseSize + extraLength; } }
internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if ( extraData.Find(0x0001) ) { if ( (versionToExtract & 0xff) < ZipConstants.VersionZip64 ) { throw new ZipException("Zip64 Extended information found but version is not valid"); } forceZip64_ = true; if ( extraData.ValueLength < 4 ) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if ( localHeader || (size == uint.MaxValue) ) { size = (ulong)extraData.ReadLong(); } if ( localHeader || (compressedSize == uint.MaxValue) ) { compressedSize = (ulong)extraData.ReadLong(); } if ( !localHeader && (offset == uint.MaxValue) ) { offset = extraData.ReadLong(); } } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } if ( extraData.Find(10) ) { if ( extraData.ValueLength < 8 ) { throw new ZipException("NTFS Extra data invalid"); } extraData.ReadInt(); while ( extraData.UnreadCount >= 4 ) { int ntfsTag = extraData.ReadShort(); int ntfsLength = extraData.ReadShort(); if ( ntfsTag == 1 ) { if ( ntfsLength >= 24 ) { long lastModification = extraData.ReadLong(); long lastAccess = extraData.ReadLong(); long createTime = extraData.ReadLong(); DateTime = System.DateTime.FromFileTime(lastModification); } break; } else { extraData.Skip(ntfsLength); } } } else if ( extraData.Find(0x5455) ) { int length = extraData.ValueLength; int flags = extraData.ReadByte(); if ( ((flags & 1) != 0) && (length >= 5) ) { int iTime = extraData.ReadInt(); DateTime = (new System.DateTime ( 1970, 1, 1, 0, 0, 0 ).ToUniversalTime() + new TimeSpan ( 0, 0, 0, iTime, 0 )).ToLocalTime(); } } }
public void PutNextEntry(ZipEntry entry) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.get_Count() == 2147483647) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int level = defaultCompressionLevel; entry.Flags &= 2048; patchEntryHeader = false; bool flag; if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0L; compressionMethod = CompressionMethod.Stored; flag = true; } else { flag = entry.Size >= 0 && entry.HasCrc; if (compressionMethod == CompressionMethod.Stored) { if (!flag) { if (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; level = 0; } } else { entry.CompressedSize = entry.Size; flag = entry.HasCrc; } } } if (!flag) { if (!base.CanPatchEntries) { entry.Flags |= 8; } else { patchEntryHeader = true; } } if (base.Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = compressionMethod; curMethod = compressionMethod; sizePatchPos = -1L; if (useZip64_ == UseZip64.On || (entry.Size < 0 && useZip64_ == UseZip64.Dynamic)) { entry.ForceZip64(); } WriteLeInt(67324752); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); if (flag) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt((int)(entry.IsCrypted ? ((int)entry.CompressedSize + 12) : entry.CompressedSize)); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = baseOutputStream_.get_Position(); } WriteLeInt(0); if (patchEntryHeader) { sizePatchPos = baseOutputStream_.get_Position(); } if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (array.Length > 65535) { throw new ZipException("Entry name too long."); } ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { zipExtraData.StartNewEntry(); if (flag) { zipExtraData.AddLeLong(entry.Size); zipExtraData.AddLeLong(entry.CompressedSize); } else { zipExtraData.AddLeLong(-1L); zipExtraData.AddLeLong(-1L); } zipExtraData.AddNewEntry(1); if (!zipExtraData.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = zipExtraData.CurrentReadIndex; } } else { zipExtraData.Delete(1); } byte[] entryData = zipExtraData.GetEntryData(); WriteLeShort(array.Length); WriteLeShort(entryData.Length); if (array.Length > 0) { baseOutputStream_.Write(array, 0, array.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.get_Position(); } if (entryData.Length > 0) { baseOutputStream_.Write(entryData, 0, entryData.Length); } offset += 30 + array.Length + entryData.Length; if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } curEntry = entry; crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(level); } size = 0L; if (entry.IsCrypted) { if (entry.Crc < 0) { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } }
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(); extraData.ReadLong(); 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 == ICSharpCode.SharpZipLib.Zip.CompressionMethod.WinZipAES) { this.ProcessAESExtraData(extraData); } }
void WriteLocalEntryHeader(ZipUpdate update) { ZipEntry entry = update.OutEntry; // TODO: Local offset will require adjusting for multi-disk zip files. entry.Offset = baseStream_.Position; // TODO: Need to clear any entry flags that dont make sense or throw an exception here. if (update.Command != UpdateCommand.Copy) { if (entry.CompressionMethod == CompressionMethod.Deflated) { if (entry.Size == 0) { // No need to compress - no data. entry.CompressedSize = entry.Size; entry.Crc = 0; entry.CompressionMethod = CompressionMethod.Stored; } } else if (entry.CompressionMethod == CompressionMethod.Stored) { entry.Flags &= ~(int)GeneralBitFlags.Descriptor; } if (HaveKeys) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= (int)GeneralBitFlags.Descriptor; } } else { entry.IsCrypted = false; } switch (useZip64_) { case UseZip64.Dynamic: if (entry.Size < 0) { entry.ForceZip64(); } break; case UseZip64.On: entry.ForceZip64(); break; case UseZip64.Off: // Do nothing. The entry itself may be using Zip64 independantly. break; } } // Write the local file header WriteLEInt(ZipConstants.LocalHeaderSignature); WriteLEShort(entry.Version); WriteLEShort(entry.Flags); WriteLEShort((byte)entry.CompressionMethod); WriteLEInt(( int )entry.DosTime); if ( !entry.HasCrc ) { // Note patch address for updating CRC later. update.CrcPatchOffset = baseStream_.Position; WriteLEInt(( int )0); } else { WriteLEInt(unchecked(( int )entry.Crc)); } if (entry.LocalHeaderRequiresZip64) { WriteLEInt(-1); WriteLEInt(-1); } else { if ( (entry.CompressedSize < 0) || (entry.Size < 0) ) { update.SizePatchOffset = baseStream_.Position; } WriteLEInt(( int )entry.CompressedSize); WriteLEInt(( int )entry.Size); } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if ( name.Length > 0xFFFF ) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if ( entry.LocalHeaderRequiresZip64 ) { ed.StartNewEntry(); // Local entry header always includes size and compressed size. // NOTE the order of these fields is reversed when compared to the normal headers! ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); ed.AddNewEntry(1); } else { ed.Delete(1); } entry.ExtraData = ed.GetEntryData(); WriteLEShort(name.Length); WriteLEShort(entry.ExtraData.Length); if ( name.Length > 0 ) { baseStream_.Write(name, 0, name.Length); } if ( entry.LocalHeaderRequiresZip64 ) { if ( !ed.Find(1) ) { throw new ZipException("Internal error cannot find extra data"); } update.SizePatchOffset = baseStream_.Position + ed.CurrentReadIndex; } if ( entry.ExtraData.Length > 0 ) { baseStream_.Write(entry.ExtraData, 0, entry.ExtraData.Length); } }
public void PutNextEntry(ZipEntry entry) { if ( entry == null ) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { method = CompressionMethod.Deflated; compressionLevel = 0; } } else { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; sizePatchPos = -1; if ( (useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic)) ) { entry.ForceZip64(); } WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)method); WriteLeInt((int)entry.DosTime); if (headerInfoAvailable == true) { WriteLeInt((int)entry.Crc); if ( entry.LocalHeaderRequiresZip64 ) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader == true) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); if ( patchEntryHeader ) { sizePatchPos = baseOutputStream_.Position; } if ( entry.LocalHeaderRequiresZip64 || patchEntryHeader ) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if ( !ed.Find(1) ) { throw new ZipException("Internal error cant find extra data"); } if ( patchEntryHeader ) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if ( name.Length > 0 ) { baseOutputStream_.Write(name, 0, name.Length); } if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) { sizePatchPos += baseOutputStream_.Position; } if ( extra.Length > 0 ) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted == true) { if (entry.Crc < 0) { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } }
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); } }
internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if (extraData.Find(0x0001)) { if ((versionToExtract & 0xff) < ZipConstants.VersionZip64) { throw new ZipException("Zip64 Extended information found but version is not valid"); } forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (size == uint.MaxValue)) { size = (ulong)extraData.ReadLong(); } if (localHeader || (compressedSize == uint.MaxValue)) { compressedSize = (ulong)extraData.ReadLong(); } if (!localHeader && (offset == uint.MaxValue)) { offset = extraData.ReadLong(); } } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } if (extraData.Find(10)) { if (extraData.ValueLength < 8) { throw new ZipException("NTFS Extra data invalid"); } extraData.ReadInt(); while (extraData.UnreadCount >= 4) { int ntfsTag = extraData.ReadShort(); int ntfsLength = extraData.ReadShort(); if (ntfsTag == 1) { if (ntfsLength >= 24) { long lastModification = extraData.ReadLong(); long lastAccess = extraData.ReadLong(); long createTime = extraData.ReadLong(); DateTime = System.DateTime.FromFileTime(lastModification); } break; } else { extraData.Skip(ntfsLength); } } } else if (extraData.Find(0x5455)) { int length = extraData.ValueLength; int flags = extraData.ReadByte(); if (((flags & 1) != 0) && (length >= 5)) { int iTime = extraData.ReadInt(); DateTime = (new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime(); } } }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if ( extraData.Find(0x0001) ) { if ( (versionToExtract & 0xff) < ZipConstants.VersionZip64 ) { throw new ZipException("Zip64 Extended information found but version is not valid"); } // The recorded size will change but remember that this is zip64. forceZip64_ = true; if ( extraData.ValueLength < 4 ) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if ( localHeader || (size == uint.MaxValue) ) { size = (ulong)extraData.ReadLong(); } if ( localHeader || (compressedSize == uint.MaxValue) ) { compressedSize = (ulong)extraData.ReadLong(); } } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ( (size == uint.MaxValue) || (compressedSize == uint.MaxValue) )) { throw new ZipException("Zip64 Extended information required but is missing."); } } /* TODO: Testing for handling of windows extra data if ( extraData.Find(10) ) { // No room for any tags. if ( extraData.ValueLength < 8 ) { throw new ZipException("NTFS Extra data invalid"); } extraData.ReadInt(); // Reserved while ( extraData.UnreadCount >= 4 ) { int ntfsTag = extraData.ReadShort(); int ntfsLength = extraData.ReadShort(); if ( ntfsTag == 1 ) { if ( ntfsLength >= 24 ) { long lastModification = extraData.ReadLong(); long lastAccess = extraData.ReadLong(); long createTime = extraData.ReadLong(); DateTime = System.DateTime.FromFileTime(lastModification); } break; } else { // An unknown NTFS tag so simply skip it. extraData.Skip(ntfsLength); } } } else */ if ( extraData.Find(0x5455) ) { int length = extraData.ValueLength; int flags = extraData.ReadByte(); // Can include other times but these are ignored. Length of data should // actually be 1 + 4 * no of bits in flags. if ( ((flags & 1) != 0) && (length >= 5) ) { int iTime = extraData.ReadInt(); DateTime = (new System.DateTime ( 1970, 1, 1, 0, 0, 0 ).ToUniversalTime() + new TimeSpan ( 0, 0, 0, iTime, 0 )).ToLocalTime(); } } }
public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { method = CompressionMethod.Deflated; compressionLevel = 0; } } else { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)method); WriteLeInt((int)entry.DosTime); if (headerInfoAvailable == true) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader == true) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); if (patchEntryHeader) { sizePatchPos = baseOutputStream_.Position; } if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { baseOutputStream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.Position; } if (extra.Length > 0) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted == true) { if (entry.Crc < 0) { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } }
public void ReadOverrunLong() { ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 }); Assert.AreEqual(4, zed.Length, "Length should be 4"); Assert.IsTrue(zed.Find(1), "Should find tag 1"); // Empty Tag bool exceptionCaught = false; try { zed.ReadLong(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); // seven bytes zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; try { zed.ReadLong(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); zed = new ZipExtraData(new byte[] { 1, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); zed.ReadLong(); exceptionCaught = false; try { zed.ReadLong(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); }
// Write the local file header // TODO: ZipHelperStream.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) { CompressionMethod method = entry.CompressionMethod; bool headerInfoAvailable = true; // How to get this? bool patchEntryHeader = false; WriteLEInt(ZipConstants.LocalHeaderSignature); WriteLEShort(entry.Version); WriteLEShort(entry.Flags); WriteLEShort((byte)method); WriteLEInt((int)entry.DosTime); if (headerInfoAvailable) { WriteLEInt((int)entry.Crc); if ( entry.LocalHeaderRequiresZip64 ) { WriteLEInt(-1); WriteLEInt(-1); } else { WriteLEInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLEInt((int)entry.Size); } } else { if (patchData != null) { patchData.CrcPatchOffset = stream_.Position; } WriteLEInt(0); // Crc if ( patchData != null ) { patchData.SizePatchOffset = stream_.Position; } // For local header both sizes appear in Zip64 Extended Information if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) { WriteLEInt(-1); WriteLEInt(-1); } else { WriteLEInt(0); // Compressed size WriteLEInt(0); // Uncompressed size } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64 && (headerInfoAvailable || patchEntryHeader)) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if ( !ed.Find(1) ) { throw new ZipException("Internal error cant find extra data"); } if ( patchData != null ) { patchData.SizePatchOffset = ed.CurrentReadIndex; } } else { ed.Delete(1); } byte[] extra = ed.GetEntryData(); WriteLEShort(name.Length); WriteLEShort(extra.Length); if ( name.Length > 0 ) { stream_.Write(name, 0, name.Length); } if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) { patchData.SizePatchOffset += stream_.Position; } if ( extra.Length > 0 ) { stream_.Write(extra, 0, extra.Length); } }
public void Skipping() { ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.AreEqual(11, zed.Length, "Length should be 11"); Assert.IsTrue(zed.Find(1), "Should find tag 1"); Assert.AreEqual(7, zed.UnreadCount); Assert.AreEqual(4, zed.CurrentReadIndex); zed.ReadByte(); Assert.AreEqual(6, zed.UnreadCount); Assert.AreEqual(5, zed.CurrentReadIndex); zed.Skip(1); Assert.AreEqual(5, zed.UnreadCount); Assert.AreEqual(6, zed.CurrentReadIndex); zed.Skip(-1); Assert.AreEqual(6, zed.UnreadCount); Assert.AreEqual(5, zed.CurrentReadIndex); zed.Skip(6); Assert.AreEqual(0, zed.UnreadCount); Assert.AreEqual(11, zed.CurrentReadIndex); bool exceptionCaught = false; try { zed.Skip(1); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Should fail to skip past end"); Assert.AreEqual(0, zed.UnreadCount); Assert.AreEqual(11, zed.CurrentReadIndex); zed.Skip(-7); Assert.AreEqual(7, zed.UnreadCount); Assert.AreEqual(4, zed.CurrentReadIndex); exceptionCaught=false; try { zed.Skip(-1); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Should fail to skip before beginning"); }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if (extraData.Find(0x0001)) { // Version required to extract is ignored here as some archivers dont set it correctly // in theory it should be version 45 or higher // The recorded size will change but remember that this is zip64. forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (size == uint.MaxValue)) { size = (ulong)extraData.ReadLong(); } if (localHeader || (compressedSize == uint.MaxValue)) { compressedSize = (ulong)extraData.ReadLong(); } if (!localHeader && (offset == uint.MaxValue)) { offset = extraData.ReadLong(); } // Disk number on which file starts is ignored } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } if (extraData.Find(10)) { // No room for any tags. if (extraData.ValueLength < 4) { throw new ZipException("NTFS Extra data invalid"); } extraData.ReadInt(); // Reserved while (extraData.UnreadCount >= 4) { int ntfsTag = extraData.ReadShort(); int ntfsLength = extraData.ReadShort(); if (ntfsTag == 1) { if (ntfsLength >= 24) { long lastModification = extraData.ReadLong(); long lastAccess = extraData.ReadLong(); long createTime = extraData.ReadLong(); DateTime = System.DateTime.FromFileTime(lastModification); } break; } else { // An unknown NTFS tag so simply skip it. extraData.Skip(ntfsLength); } } } else if (extraData.Find(0x5455)) { int length = extraData.ValueLength; int flags = extraData.ReadByte(); // Can include other times but these are ignored. Length of data should // actually be 1 + 4 * no of bits in flags. if (((flags & 1) != 0) && (length >= 5)) { int iTime = extraData.ReadInt(); DateTime = (new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime(); } } if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(extraData); } }
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); } }
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 ICSharpCode.SharpZipLib.Zip.UseZip64.On: outEntry.ForceZip64(); break; case ICSharpCode.SharpZipLib.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); } }
/// <summary> /// Starts a new Zip entry. It automatically closes the previous /// entry if present. /// All entry elements bar name are optional, but must be correct if present. /// If the compression method is stored and the output is not patchable /// the compression for that entry is automatically changed to deflate level 0 /// </summary> /// <param name="entry"> /// the entry. /// </param> /// <exception cref="System.ArgumentNullException"> /// if entry passed is null. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O error occured. /// </exception> /// <exception cref="System.InvalidOperationException"> /// if stream was finished /// </exception> /// <exception cref="ZipException"> /// Too many entries in the Zip file<br/> /// Entry name is too long<br/> /// Finish has already been called<br/> /// </exception> public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int) GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Write the local file header WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte) entry.CompressionMethodForHeader); WriteLeInt((int) entry.DosTime); // TODO: Refactor header writing. Its done in several places. if (headerInfoAvailable) { WriteLeInt((int) entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int) entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int) entry.CompressedSize); WriteLeInt((int) entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); // Crc if (patchEntryHeader) { sizePatchPos = baseOutputStream_.Position; } // For local header both sizes appear in Zip64 Extended Information if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); // Compressed size WriteLeInt(0); // Uncompressed size } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } #if !NET_1_1 && !NETCF_2_0 if (entry.AESKeySize > 0) { AddExtraDataAES(entry, ed); } #endif byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { baseOutputStream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.Position; } if (extra.Length > 0) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) offset += entry.AESOverheadSize; // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted) { #if !NET_1_1 && !NETCF_2_0 if (entry.AESKeySize > 0) { WriteAESHeader(entry); } else #endif { if (entry.Crc < 0) { // so testing Zip will says its ok WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } } }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { var extraData = new ZipExtraData(extra); if (extraData.Find(0x0001)) { // Version required to extract is ignored here as some archivers dont set it correctly // in theory it should be version 45 or higher // The recorded size will change but remember that this is zip64. forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (size == uint.MaxValue)) { size = (ulong) extraData.ReadLong(); } if (localHeader || (compressedSize == uint.MaxValue)) { compressedSize = (ulong) extraData.ReadLong(); } if (!localHeader && (offset == uint.MaxValue)) { offset = extraData.ReadLong(); } // Disk number on which file starts is ignored } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } if (extraData.Find(10)) { // No room for any tags. if (extraData.ValueLength < 4) { throw new ZipException("NTFS Extra data invalid"); } extraData.ReadInt(); // Reserved while (extraData.UnreadCount >= 4) { int ntfsTag = extraData.ReadShort(); int ntfsLength = extraData.ReadShort(); if (ntfsTag == 1) { if (ntfsLength >= 24) { long lastModification = extraData.ReadLong(); long lastAccess = extraData.ReadLong(); long createTime = extraData.ReadLong(); DateTime = DateTime.FromFileTime(lastModification); } break; } else { // An unknown NTFS tag so simply skip it. extraData.Skip(ntfsLength); } } } else if (extraData.Find(0x5455)) { int length = extraData.ValueLength; int flags = extraData.ReadByte(); // Can include other times but these are ignored. Length of data should // actually be 1 + 4 * no of bits in flags. if (((flags & 1) != 0) && (length >= 5)) { int iTime = extraData.ReadInt(); DateTime = (new DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime(); } } if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(extraData); } }
internal void ProcessExtraData(bool localHeader) { ZipExtraData data = new ZipExtraData(this.extra); if (data.Find(1)) { if ((this.versionToExtract & 0xff) < 0x2d) { throw new ZipException("Zip64 Extended information found but version is not valid"); } this.forceZip64_ = true; if (data.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (this.size == 0xffffffffL)) { this.size = (ulong)data.ReadLong(); } if (localHeader || (this.compressedSize == 0xffffffffL)) { this.compressedSize = (ulong)data.ReadLong(); } if (!localHeader && (this.offset == 0xffffffffL)) { this.offset = data.ReadLong(); } } else if (((this.versionToExtract & 0xff) >= 0x2d) && ((this.size == 0xffffffffL) || (this.compressedSize == 0xffffffffL))) { throw new ZipException("Zip64 Extended information required but is missing."); } if (data.Find(10)) { if (data.ValueLength < 8) { throw new ZipException("NTFS Extra data invalid"); } data.ReadInt(); while (data.UnreadCount >= 4) { int num = data.ReadShort(); int amount = data.ReadShort(); if (num == 1) { if (amount >= 0x18) { long fileTime = data.ReadLong(); data.ReadLong(); data.ReadLong(); this.DateTime = System.DateTime.FromFileTime(fileTime); return; } return; } data.Skip(amount); } } else if (data.Find(0x5455)) { int valueLength = data.ValueLength; if (((data.ReadByte() & 1) != 0) && (valueLength >= 5)) { int seconds = data.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(); } } }
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(); extraData.ReadShort(); int num3 = extraData.ReadByte(); int num4 = extraData.ReadShort(); this._aesVer = num2; this._aesEncryptionStrength = num3; this.method = (ICSharpCode.SharpZipLib.Zip.CompressionMethod) num4; }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if ( extraData.Find(0x0001) ) { // Version required to extract is ignored here as some archivers dont set it correctly // in theory it should be version 45 or higher // The recorded size will change but remember that this is zip64. forceZip64_ = true; if ( extraData.ValueLength < 4 ) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if ( localHeader || (size == uint.MaxValue) ) { size = (ulong)extraData.ReadLong(); } if ( localHeader || (compressedSize == uint.MaxValue) ) { compressedSize = (ulong)extraData.ReadLong(); } if ( !localHeader && (offset == uint.MaxValue) ) { offset = extraData.ReadLong(); } // Disk number on which file starts is ignored } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) ) { throw new ZipException("Zip64 Extended information required but is missing."); } } dateTime = GetDateTime(extraData); if (method == CompressionMethod.WinZipAES) { ProcessAESExtraData(extraData); } }
private void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) { CompressionMethod compressionMethod = entry.CompressionMethod; bool flag = true; bool flag2 = false; WriteLEInt(67324752); WriteLEShort(entry.Version); WriteLEShort(entry.Flags); WriteLEShort((byte)compressionMethod); WriteLEInt((int)entry.DosTime); if (flag) { WriteLEInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLEInt(-1); WriteLEInt(-1); } else { WriteLEInt((int)(entry.IsCrypted ? ((int)entry.CompressedSize + 12) : entry.CompressedSize)); WriteLEInt((int)entry.Size); } } else { if (patchData != null) { patchData.CrcPatchOffset = stream_.get_Position(); } WriteLEInt(0); if (patchData != null) { patchData.SizePatchOffset = stream_.get_Position(); } if (entry.LocalHeaderRequiresZip64 && flag2) { WriteLEInt(-1); WriteLEInt(-1); } else { WriteLEInt(0); WriteLEInt(0); } } byte[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (array.Length > 65535) { throw new ZipException("Entry name too long."); } ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64 && (flag || flag2)) { zipExtraData.StartNewEntry(); if (flag) { zipExtraData.AddLeLong(entry.Size); zipExtraData.AddLeLong(entry.CompressedSize); } else { zipExtraData.AddLeLong(-1L); zipExtraData.AddLeLong(-1L); } zipExtraData.AddNewEntry(1); if (!zipExtraData.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchData != null) { patchData.SizePatchOffset = zipExtraData.CurrentReadIndex; } } else { zipExtraData.Delete(1); } byte[] entryData = zipExtraData.GetEntryData(); WriteLEShort(array.Length); WriteLEShort(entryData.Length); if (array.Length > 0) { stream_.Write(array, 0, array.Length); } if (entry.LocalHeaderRequiresZip64 && flag2) { patchData.SizePatchOffset += stream_.get_Position(); } if (entryData.Length > 0) { stream_.Write(entryData, 0, entryData.Length); } }
public void PutNextEntry(ZipEntry entry) { bool hasCrc; if (entry == null) { throw new ArgumentNullException("entry"); } if (this.entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (this.curEntry != null) { this.CloseEntry(); } if (this.entries.Count == 0x7fffffff) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int defaultCompressionLevel = this.defaultCompressionLevel; entry.Flags &= 0x800; this.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 (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; defaultCompressionLevel = 0; } } else { entry.CompressedSize = entry.Size; hasCrc = entry.HasCrc; } } } if (!hasCrc) { if (!base.CanPatchEntries) { entry.Flags |= 8; } else { this.patchEntryHeader = true; } } if (base.Password != null) { entry.IsCrypted = true; if (entry.Crc < 0L) { entry.Flags |= 8; } } entry.Offset = this.offset; entry.CompressionMethod = compressionMethod; this.curMethod = compressionMethod; this.sizePatchPos = -1L; if ((this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.On) || ((entry.Size < 0L) && (this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.Dynamic))) { entry.ForceZip64(); } this.WriteLeInt(0x4034b50); this.WriteLeShort(entry.Version); this.WriteLeShort(entry.Flags); this.WriteLeShort((byte)entry.CompressionMethodForHeader); this.WriteLeInt((int)entry.DosTime); if (hasCrc) { 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 (this.patchEntryHeader) { this.crcPatchPos = base.baseOutputStream_.Position; } this.WriteLeInt(0); if (this.patchEntryHeader) { this.sizePatchPos = base.baseOutputStream_.Position; } if (entry.LocalHeaderRequiresZip64 || this.patchEntryHeader) { 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 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 (this.patchEntryHeader) { this.sizePatchPos = extraData.CurrentReadIndex; } } else { extraData.Delete(1); } if (entry.AESKeySize > 0) { AddExtraDataAES(entry, extraData); } byte[] entryData = extraData.GetEntryData(); this.WriteLeShort(buffer.Length); this.WriteLeShort(entryData.Length); if (buffer.Length > 0) { base.baseOutputStream_.Write(buffer, 0, buffer.Length); } if (entry.LocalHeaderRequiresZip64 && this.patchEntryHeader) { this.sizePatchPos += base.baseOutputStream_.Position; } if (entryData.Length > 0) { base.baseOutputStream_.Write(entryData, 0, entryData.Length); } this.offset += (30 + buffer.Length) + entryData.Length; if (entry.AESKeySize > 0) { this.offset += entry.AESOverheadSize; } this.curEntry = entry; this.crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { base.deflater_.Reset(); base.deflater_.SetLevel(defaultCompressionLevel); } this.size = 0L; if (entry.IsCrypted) { if (entry.AESKeySize > 0) { this.WriteAESHeader(entry); } else if (entry.Crc < 0L) { this.WriteEncryptionHeader(entry.DosTime << 0x10); } else { this.WriteEncryptionHeader(entry.Crc); } } }
internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if (!extraData.Find(1)) { if (((this.versionToExtract & 0xff) >= 0x2d) && ((this.size == 0xffffffffUL) || (this.compressedSize == 0xffffffffUL))) { throw new ZipException("Zip64 Extended information required but is missing."); } } else { this.forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (this.size == 0xffffffffUL)) { this.size = (ulong)extraData.ReadLong(); } if (localHeader || (this.compressedSize == 0xffffffffUL)) { this.compressedSize = (ulong)extraData.ReadLong(); } if (!localHeader && (this.offset == 0xffffffffUL)) { this.offset = extraData.ReadLong(); } } if (!extraData.Find(10)) { if (extraData.Find(0x5455)) { int valueLength = extraData.ValueLength; if (((extraData.ReadByte() & 1) != 0) && (valueLength >= 5)) { int seconds = extraData.ReadInt(); this.DateTime = (new System.DateTime(0x7b2, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime(); } } } else { if (extraData.ValueLength < 4) { throw new ZipException("NTFS Extra data invalid"); } extraData.ReadInt(); while (extraData.UnreadCount >= 4) { int amount = extraData.ReadShort(); if (extraData.ReadShort() == 1) { if (amount >= 0x18) { long fileTime = extraData.ReadLong(); extraData.ReadLong(); extraData.ReadLong(); this.DateTime = System.DateTime.FromFileTime(fileTime); } break; } extraData.Skip(amount); } } if (this.method == ICSharpCode.SharpZipLib.Zip.CompressionMethod.WinZipAES) { this.ProcessAESExtraData(extraData); } }
public void ReadOverrunLong() { ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 }); Assert.AreEqual(4, zed.Length, "Length should be 4"); Assert.IsTrue(zed.Find(1), "Should find tag 1"); // Empty Tag bool exceptionCaught = false; try { zed.ReadLong(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); // seven bytes zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; try { zed.ReadLong(); } catch (ZipException) { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); zed = new ZipExtraData(new byte[] { 1, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9F�5���5���5��5@�5��5��5��5�թ5���5���5�έ5��5���5@թ5��5P��5@Ԣ5 ��5���5 �5��5���5��5P!�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5�h�5�N�5 �5�έ5PN�5@a�50;�5�߮5�M�50O�5�M�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5K�5��5���5��5�!�5F�5���5���5��5p�5��5��5�5�թ5���5`"�5�έ5��5���5PN�5@a�50;�5`�5 �5@թ5��5P��5@Ԣ5P�5��5 �5��5��5��5P!�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5@K�5p:�5���5��5�!�5F�5���5���5��5P=�5�>�5�>�5�?�5�թ5���5�F�5�έ5��5���5PN�5@a�50;�5@<�5<�5@թ5��5P��5@Ԣ50@�5�@�5 �5��5�C�5��5P!�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5pK�5@^�5���5��5 m�5Po�5���5���5��5 a�5pb�5�b�5�c�5�թ5���5�o�5�έ5��5���5PN�5@a�50;�5`�5�_�5@թ5��5P��5@Ԣ5d�5�d�5�f�5�h�5�f�5�j�5�l�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5�h�5�Q�5 �5�έ5PN�5@a�50;�5�߮5�P�5�P�5@Q�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5�K�5p��5@Ԣ5��5���5���5���5���5��5P��5���5Ћ�5���5�թ5���5���5�έ5��5���5PN�5@a�50;�5@��5��5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5 i�5pT�5 �5�έ5PN�5@a�50;�5�߮5PS�5�S�5�S�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5�K�5�5���5��5н�5P��5���5���5��5�5`��5���5���5�թ5���5���5�έ5��5���5@թ5��5P��5@Ԣ5�5���5��5P��5�5���59�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5L�5�5 �5�έ5PN�5@a�50;�5�6�ֺ5 ��5�ֺ5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�50L�50ߺ5���5��5��5�5���5���5��5�5`�5��5��5�թ5���5p�5�έ5��5���5@թ5��5P��5@Ԣ5��5��50�5p�5p�5��5��5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5Pi�5PW�5 �5�έ5PN�5@a�50;�5�߮5�U�50V�5�V�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5`L�5��5���5��5��5�5���5���5��5� �5� �5�5 �5�թ5���5��5�έ5��5���5@թ5��5P��5@Ԣ5`�5��50�5p�5��5��5��5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5�L�5�-�5���5��5н�5P��5���5���5��5�0�5 2�5P2�5p3�5�թ5���5P9�5�έ5��5���5PN�5@a�50;�5�/�5@/�5@թ5��5P��5@Ԣ5�3�5@4�5��5P��5�6�5���59�5Ѐ�5�F�5���5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5`�5�N�5 �5�έ5PN�5ж�5 N�5�߮5�M�50O�5�M�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5��5�Q�5 �5�έ5PN�5ж�5 N�5�߮5�P�5�P�5@Q�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5��5pT�5 �5�έ5PN�5ж�5 N�5�߮5PS�5�S�5�S�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5��5PW�5 �5�έ5PN�5ж�5 N�5�߮5�U�50V�5�V�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5 ��5�5 �5�έ5PN�5ж�5 N�5�6�ֺ5 ��5�ֺ5YukonServerContainer_Cryptencrypted_filenametableconfigfile%X%X%X%X%Xe:\sql9_sp2_t\sql\picasso\engine\src\pf\ds\pfssfilesys.cppConfigFile\VersionHighConfigFile\VersionLowConfigFile\IsEncryptedConfigFile\CSPNameConfigFile\CSPTypeConfigFile\EncryptionAlgorithmConfigFile\HashAlgorithmConfigFile\KeyLengthnametable.tmpPFSSDirectory::CreateDirPFSSDirectory::RenameDirPFSSDirectory::DeleteDirPFSSDirectory::OpenFilePFSSDirectory::RenameFilePFSSDirectory::CopyFileWPFSSDirectory::MoveFileWPFSSDirectory::DeleteFileWPFSSDirectory::GetSize�r 6��5���5�}�5�q�5Pr�5�r�5ps�5��5�~�5�s�5�s�5�s�5t�5=�5`t�5�t�5�t�5�}�5�"�5 ��5@߹5�t�5p��5u�5 u�5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5�έ5@Ԣ5�έ5�{�5�o�5���5 ��5�"�5p�5�έ5�6�6���5���5p��5���50�5��5�"�5 ��5���50��50��50��5 �5 �5 �50�5�έ5@Ԣ5��5��5���5�!�5�5��5�{�5�N�5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�"�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5@�5��5`�5P�5N�5@Ԣ5@Ԣ5�έ5�έ5@Ԣ5`��5�5�5 �5��5��5@�5R�5��5��5@N�5@a�50;�5@�5��5��5��5��5�6�u�5�O�5�O�5`�5��50͈5��5P��5�!�5�5��5�{�5P��5P-�5���5@z�5@z�5@z�5@z�5��5�x�5�~�5���5Ѐ�5��5�x�50w�5�x�50w�5 ��5@߹5P�5�p�5@�5@��5`��5�t�5p��5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5��5`c�5�έ5�{�5�o�5��5��5��5��5���5���5�έ5�6@�5Н�5�M�5`F�5p"�5P"�5"�5p��5�r 6��5���5�}�5�q�5Pr�5�r�5ps�5��5�~�5�s�5�s�5�s�5t�5=�5`t�5�t�5�t�5�}�5"�5 ��5@߹5�t�5p��5u�5 u�5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5�έ5@Ԣ5�έ5�{�5�o�5��5��5�!�5��50�5P��5P-�5���5@z�5@z�5@z�5@z�5��5�x�5�~�5���5Ѐ�5��5�x�50w�5�x�50w�5 ��5@߹5P�5�p�5@�5@��5`��5�t�5p��5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5��5`c�5�έ5�{�5�o�5�5��5��5��5���5���5�έ5�6@�5���5н�5�5P�5�5���5 ��5p�5��5P+�5�.�5p�5��5 �5��5��5�5 �5@�5 �5p�5��50�50�5��5@Ԣ5�(�5M�5��5@Ԣ5�5�]6�]6 ^6`^6�^6PFXmlEncodeAndAddStringe:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfxmlconvert.cppPFBufferedMemConnection::Connecte:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfbufferedstream.cpp�N�5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5pN�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5P3�5PN�5�4�5�6 5�5P�5p5�5@Ԣ5@߹5 4�5@N�5@a�50;�5�5�507�5�5���5�O�5 N�5�u�5�O�5�O�5���5�u�5PFCompressedStream::Inite:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfcompressedstream.cppCompressed streamPFCompressedStream::CopyTo�N�5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5pN�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5�>�50<�5A�5P<�5`A�5p=�5`C�5�=�5�=�5�@�5�?�5@N�5@a�50;�5�C�5pF�5��5@=�5�G�5 N�5�<�5�<�5=�5p<�5PJ�5PFChunkCursor::GetNextBlocke:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pftcp.cppPCXAcceptBuffer::AsyncAcceptlocalhost(local)localPFIXAConnectionTransport::SetPasswordPFIXAConnectionTransport::GetPasswordP��5��5P��5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5`��5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5���5�w�5�o�5���5k�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5`��5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5���5P�5p��5PFSOAPMessage::BeginMessagee:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfsoapmsg.cppPFHTTPConnection::Connecte:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfhttp.cppMSOLAP 9.0 ClientPFHTTPConnection::RunProxyAutodetectionStepPFHTTPConnection::CreateStreamPFHTTPStream::WriteHttpDataContent-Type:
/// <summary> /// Test a local header against that provided from the central directory /// </summary> /// <param name="entry"> /// The entry to test against /// </param> /// <param name="tests">The type of <see cref="HeaderTest">tests</see> to carry out.</param> /// <returns>The offset of the entries data in the file</returns> long TestLocalHeader(ZipEntry entry, HeaderTest tests) { lock(baseStream_) { bool testHeader = (tests & HeaderTest.Header) != 0; bool testData = (tests & HeaderTest.Extract) != 0; baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin); if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) { throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset)); } short extractVersion = ( short ) (ReadLEUshort() & 0x00ff); short localFlags = ( short )ReadLEUshort(); short compressionMethod = ( short )ReadLEUshort(); short fileTime = ( short )ReadLEUshort(); short fileDate = ( short )ReadLEUshort(); uint crcValue = ReadLEUint(); long compressedSize = ReadLEUint(); long size = ReadLEUint(); int storedNameLength = ReadLEUshort(); int extraDataLength = ReadLEUshort(); byte[] nameData = new byte[storedNameLength]; StreamUtils.ReadFully(baseStream_, nameData); byte[] extraData = new byte[extraDataLength]; StreamUtils.ReadFully(baseStream_, extraData); ZipExtraData localExtraData = new ZipExtraData(extraData); // Extra data / zip64 checks if (localExtraData.Find(1)) { // 2010-03-04 Forum 10512: removed checks for version >= ZipConstants.VersionZip64 // and size or compressedSize = MaxValue, due to rogue creators. size = localExtraData.ReadLong(); compressedSize = localExtraData.ReadLong(); if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0) { // These may be valid if patched later if ( (size != -1) && (size != entry.Size)) { throw new ZipException("Size invalid for descriptor"); } if ((compressedSize != -1) && (compressedSize != entry.CompressedSize)) { throw new ZipException("Compressed size invalid for descriptor"); } } } else { // No zip64 extra data but entry requires it. if ((extractVersion >= ZipConstants.VersionZip64) && (((uint)size == uint.MaxValue) || ((uint)compressedSize == uint.MaxValue))) { throw new ZipException("Required Zip64 extended information missing"); } } if ( testData ) { if ( entry.IsFile ) { if ( !entry.IsCompressionMethodSupported() ) { throw new ZipException("Compression method not supported"); } if ( (extractVersion > ZipConstants.VersionMadeBy) || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64)) ) { throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion)); } if ( (localFlags & ( int )(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0 ) { throw new ZipException("The library does not support the zip version required to extract this entry"); } } } if (testHeader) { if ((extractVersion <= 63) && // Ignore later versions as we dont know about them.. (extractVersion != 10) && (extractVersion != 11) && (extractVersion != 20) && (extractVersion != 21) && (extractVersion != 25) && (extractVersion != 27) && (extractVersion != 45) && (extractVersion != 46) && (extractVersion != 50) && (extractVersion != 51) && (extractVersion != 52) && (extractVersion != 61) && (extractVersion != 62) && (extractVersion != 63) ) { throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion)); } // Local entry flags dont have reserved bit set on. if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0) { throw new ZipException("Reserved bit flags cannot be set."); } // Encryption requires extract version >= 20 if (((localFlags & (int)GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20)) { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } // Strong encryption requires encryption flag to be set and extract version >= 50. if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) { if ((localFlags & (int)GeneralBitFlags.Encrypted) == 0) { throw new ZipException("Strong encryption flag set but encryption flag is not set"); } if (extractVersion < 50) { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } } // Patched entries require extract version >= 27 if (((localFlags & (int)GeneralBitFlags.Patched) != 0) && (extractVersion < 27)) { throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion)); } // Central header flags match local entry flags. if (localFlags != entry.Flags) { throw new ZipException("Central header/local header flags mismatch"); } // Central header compression method matches local entry if (entry.CompressionMethod != (CompressionMethod)compressionMethod) { throw new ZipException("Central header/local header compression method mismatch"); } if (entry.Version != extractVersion) { throw new ZipException("Extract version mismatch"); } // Strong encryption and extract version match if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) { if (extractVersion < 62) { throw new ZipException("Strong encryption flag set but version not high enough"); } } if ((localFlags & (int)GeneralBitFlags.HeaderMasked) != 0) { if ((fileTime != 0) || (fileDate != 0)) { throw new ZipException("Header masked set but date/time values non-zero"); } } if ((localFlags & (int)GeneralBitFlags.Descriptor) == 0) { if (crcValue != (uint)entry.Crc) { throw new ZipException("Central header/local header crc mismatch"); } } // Crc valid for empty entry. // This will also apply to streamed entries where size isnt known and the header cant be patched if ((size == 0) && (compressedSize == 0)) { if (crcValue != 0) { throw new ZipException("Invalid CRC for empty entry"); } } // TODO: make test more correct... can't compare lengths as was done originally as this can fail for MBCS strings // Assuming a code page at this point is not valid? Best is to store the name length in the ZipEntry probably if (entry.Name.Length > storedNameLength) { throw new ZipException("File name length mismatch"); } // Name data has already been read convert it and compare. string localName = ZipConstants.ConvertToStringExt(localFlags, nameData); // Central directory and local entry name match if (localName != entry.Name) { throw new ZipException("Central header and local header file name mismatch"); } // Directories have zero actual size but can have compressed size if (entry.IsDirectory) { if (size > 0) { throw new ZipException("Directory cannot have size"); } // There may be other cases where the compressed size can be greater than this? // If so until details are known we will be strict. if (entry.IsCrypted) { if (compressedSize > ZipConstants.CryptoHeaderSize + 2) { throw new ZipException("Directory compressed size invalid"); } } else if (compressedSize > 2) { // When not compressed the directory size can validly be 2 bytes // if the true size wasnt known when data was originally being written. // NOTE: Versions of the library 0.85.4 and earlier always added 2 bytes throw new ZipException("Directory compressed size invalid"); } } if (!ZipNameTransform.IsValidName(localName, true)) { throw new ZipException("Name is invalid"); } } // Tests that apply to both data and header. // Size can be verified only if it is known in the local header. // it will always be known in the central header. if (((localFlags & (int)GeneralBitFlags.Descriptor) == 0) || ((size > 0 || compressedSize > 0) && entry.Size > 0)) { if ((size != 0) && (size != entry.Size)) { throw new ZipException( string.Format("Size mismatch between central header({0}) and local header({1})", entry.Size, size)); } if ((compressedSize != 0) && (compressedSize != entry.CompressedSize && compressedSize != 0xFFFFFFFF && compressedSize != -1)) { throw new ZipException( string.Format("Compressed size mismatch between central header({0}) and local header({1})", entry.CompressedSize, compressedSize)); } } int extraLength = storedNameLength + extraDataLength; return offsetOfFirstEntry + entry.Offset + ZipConstants.LocalHeaderBaseSize + extraLength; } }
/// <summary> /// Process extra data fields updating the entry based on the contents. /// </summary> /// <param name="localHeader">True if the extra data fields should be handled /// for a local header, rather than for a central header. /// </param> internal void ProcessExtraData(bool localHeader) { ZipExtraData extraData = new ZipExtraData(this.extra); if (extraData.Find(0x0001)) { if ((versionToExtract & 0xff) < ZipConstants.VersionZip64) { throw new ZipException("Zip64 Extended information found but version is not valid"); } // The recorded size will change but remember that this is zip64. forceZip64_ = true; if (extraData.ValueLength < 4) { throw new ZipException("Extra data extended Zip64 information length is invalid"); } if (localHeader || (size == uint.MaxValue)) { size = (ulong)extraData.ReadLong(); } if (localHeader || (compressedSize == uint.MaxValue)) { compressedSize = (ulong)extraData.ReadLong(); } } else { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))) { throw new ZipException("Zip64 Extended information required but is missing."); } } /* TODO: Testing for handling of windows extra data * if ( extraData.Find(10) ) { * // No room for any tags. * if ( extraData.ValueLength < 8 ) { * throw new ZipException("NTFS Extra data invalid"); * } * * extraData.ReadInt(); // Reserved * * while ( extraData.UnreadCount >= 4 ) { * int ntfsTag = extraData.ReadShort(); * int ntfsLength = extraData.ReadShort(); * if ( ntfsTag == 1 ) { * if ( ntfsLength >= 24 ) { * long lastModification = extraData.ReadLong(); * long lastAccess = extraData.ReadLong(); * long createTime = extraData.ReadLong(); * * DateTime = System.DateTime.FromFileTime(lastModification); * } * break; * } * else { * // An unknown NTFS tag so simply skip it. * extraData.Skip(ntfsLength); * } * } * } * else */ if (extraData.Find(0x5455)) { int length = extraData.ValueLength; int flags = extraData.ReadByte(); // Can include other times but these are ignored. Length of data should // actually be 1 + 4 * no of bits in flags. if (((flags & 1) != 0) && (length >= 5)) { int iTime = extraData.ReadInt(); DateTime = (new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime(); } } }
/// <summary> /// Starts a new Zip entry. It automatically closes the previous /// entry if present. /// All entry elements bar name are optional, but must be correct if present. /// If the compression method is stored and the output is not patchable /// the compression for that entry is automatically changed to deflate level 0 /// </summary> /// <param name="entry"> /// the entry. /// </param> /// <exception cref="System.ArgumentNullException"> /// if entry passed is null. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O error occured. /// </exception> /// <exception cref="System.InvalidOperationException"> /// if stream was finished /// </exception> /// <exception cref="ZipException"> /// Too many entries in the Zip file<br/> /// Entry name is too long<br/> /// Finish has already been called<br/> /// </exception> public void PutNextEntry(ZipEntryM entry) { if (entry == null) { //throw new ArgumentNullException(//nameof//(entry)); } if (entries == null) { //throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { //throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc && entry.CompressedSize >= 0; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Write the local file header WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); // TODO: Refactor header writing. Its done in several places. if (headerInfoAvailable) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); // Crc if (patchEntryHeader) { sizePatchPos = baseOutputStream_.Position; } // For local header both sizes appear in Zip64 Extended Information if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); // Compressed size WriteLeInt(0); // Uncompressed size } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { //throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { //throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } if (entry.AESKeySize > 0) { AddExtraDataAES(entry, ed); } byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { baseOutputStream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.Position; } if (extra.Length > 0) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted) { if (entry.AESKeySize > 0) { WriteAESHeader(entry); } else { if (entry.Crc < 0) // so testing Zip will says its ok { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } } }
public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (this.entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (this.curEntry != null) { this.CloseEntry(); } if (this.entries.Count == 2147483647) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int level = this.defaultCompressionLevel; entry.Flags &= 2048; this.patchEntryHeader = false; bool flag; if (entry.Size == 0L) { entry.CompressedSize = entry.Size; entry.Crc = 0L; compressionMethod = CompressionMethod.Stored; flag = true; } else { flag = (entry.Size >= 0L && entry.HasCrc && entry.CompressedSize >= 0L); if (compressionMethod == CompressionMethod.Stored) { if (!flag) { if (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; level = 0; } } else { entry.CompressedSize = entry.Size; flag = entry.HasCrc; } } } if (!flag) { if (!base.CanPatchEntries) { entry.Flags |= 8; } else { this.patchEntryHeader = true; } } if (base.Password != null) { entry.IsCrypted = true; if (entry.Crc < 0L) { entry.Flags |= 8; } } entry.Offset = this.offset; entry.CompressionMethod = compressionMethod; this.curMethod = compressionMethod; this.sizePatchPos = -1L; if (this.useZip64_ == UseZip64.On || (entry.Size < 0L && this.useZip64_ == UseZip64.Dynamic)) { entry.ForceZip64(); } this.WriteLeInt(67324752); this.WriteLeShort(entry.Version); this.WriteLeShort(entry.Flags); this.WriteLeShort((int)((byte)entry.CompressionMethodForHeader)); 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) : ((int)entry.CompressedSize + 12)); this.WriteLeInt((int)entry.Size); } } else { if (this.patchEntryHeader) { this.crcPatchPos = this.baseOutputStream_.Position; } this.WriteLeInt(0); if (this.patchEntryHeader) { this.sizePatchPos = this.baseOutputStream_.Position; } if (entry.LocalHeaderRequiresZip64 || this.patchEntryHeader) { this.WriteLeInt(-1); this.WriteLeInt(-1); } else { this.WriteLeInt(0); this.WriteLeInt(0); } } byte[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (array.Length > 65535) { throw new ZipException("Entry name too long."); } ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { zipExtraData.StartNewEntry(); if (flag) { zipExtraData.AddLeLong(entry.Size); zipExtraData.AddLeLong(entry.CompressedSize); } else { zipExtraData.AddLeLong(-1L); zipExtraData.AddLeLong(-1L); } zipExtraData.AddNewEntry(1); if (!zipExtraData.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (this.patchEntryHeader) { this.sizePatchPos = (long)zipExtraData.CurrentReadIndex; } } else { zipExtraData.Delete(1); } if (entry.AESKeySize > 0) { ZipOutputStream.AddExtraDataAES(entry, zipExtraData); } byte[] entryData = zipExtraData.GetEntryData(); this.WriteLeShort(array.Length); this.WriteLeShort(entryData.Length); if (array.Length > 0) { this.baseOutputStream_.Write(array, 0, array.Length); } if (entry.LocalHeaderRequiresZip64 && this.patchEntryHeader) { this.sizePatchPos += this.baseOutputStream_.Position; } if (entryData.Length > 0) { this.baseOutputStream_.Write(entryData, 0, entryData.Length); } this.offset += (long)(30 + array.Length + entryData.Length); if (entry.AESKeySize > 0) { this.offset += (long)entry.AESOverheadSize; } this.curEntry = entry; this.crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { this.deflater_.Reset(); this.deflater_.SetLevel(level); } this.size = 0L; if (entry.IsCrypted) { if (entry.AESKeySize > 0) { this.WriteAESHeader(entry); } else if (entry.Crc < 0L) { this.WriteEncryptionHeader(entry.DosTime << 16); } else { this.WriteEncryptionHeader(entry.Crc); } } }
// For AES the method in the entry is 99, and the real compression method is in the extradata // private void ProcessAESExtraData(ZipExtraData extraData) { if (extraData.Find(0x9901)) { // Set version and flag for Zipfile.CreateAndInitDecryptionStream versionToExtract = ZipConstants.VERSION_AES; // Ver 5.1 = AES see "Version" getter // Set StrongEncryption flag for ZipFile.CreateAndInitDecryptionStream Flags = Flags | (int)GeneralBitFlags.StrongEncryption; // // Unpack AES extra data field see http://www.winzip.com/aes_info.htm int length = extraData.ValueLength; // Data size currently 7 if (length < 7) throw new ZipException("AES Extra Data Length " + length + " invalid."); int ver = extraData.ReadShort(); // Version number (1=AE-1 2=AE-2) int vendorId = extraData.ReadShort(); // 2-character vendor ID 0x4541 = "AE" int encrStrength = extraData.ReadByte(); // encryption strength 1 = 128 2 = 192 3 = 256 int actualCompress = extraData.ReadShort(); // The actual compression method used to compress the file _aesVer = ver; _aesEncryptionStrength = encrStrength; method = (CompressionMethod)actualCompress; } else throw new ZipException("AES Extra Data missing"); }
public void PutNextEntry(ZipEntry entry) { bool hasCrc; if (entry == null) { throw new ArgumentNullException("entry"); } if (this.entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (this.curEntry != null) { this.CloseEntry(); } if (this.entries.Count == 0x7fffffff) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int defaultCompressionLevel = this.defaultCompressionLevel; entry.Flags &= 0x800; this.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) && (entry.CompressedSize >= 0L); if (compressionMethod == CompressionMethod.Stored) { if (!hasCrc) { if (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; defaultCompressionLevel = 0; } } else { entry.CompressedSize = entry.Size; hasCrc = entry.HasCrc; } } } if (!hasCrc) { if (!base.CanPatchEntries) { entry.Flags |= 8; } else { this.patchEntryHeader = true; } } if (base.Password != null) { entry.IsCrypted = true; if (entry.Crc < 0L) { entry.Flags |= 8; } } entry.Offset = this.offset; entry.CompressionMethod = compressionMethod; this.curMethod = compressionMethod; this.sizePatchPos = -1L; if ((this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.On) || ((entry.Size < 0L) && (this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.Dynamic))) { entry.ForceZip64(); } this.WriteLeInt(0x4034b50); this.WriteLeShort(entry.Version); this.WriteLeShort(entry.Flags); this.WriteLeShort((byte) entry.CompressionMethodForHeader); this.WriteLeInt((int) entry.DosTime); if (hasCrc) { 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 (this.patchEntryHeader) { this.crcPatchPos = base.baseOutputStream_.Position; } this.WriteLeInt(0); if (this.patchEntryHeader) { this.sizePatchPos = base.baseOutputStream_.Position; } if (entry.LocalHeaderRequiresZip64 || this.patchEntryHeader) { 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 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 (this.patchEntryHeader) { this.sizePatchPos = extraData.CurrentReadIndex; } } else { extraData.Delete(1); } if (entry.AESKeySize > 0) { AddExtraDataAES(entry, extraData); } byte[] entryData = extraData.GetEntryData(); this.WriteLeShort(buffer.Length); this.WriteLeShort(entryData.Length); if (buffer.Length > 0) { base.baseOutputStream_.Write(buffer, 0, buffer.Length); } if (entry.LocalHeaderRequiresZip64 && this.patchEntryHeader) { this.sizePatchPos += base.baseOutputStream_.Position; } if (entryData.Length > 0) { base.baseOutputStream_.Write(entryData, 0, entryData.Length); } this.offset += (30 + buffer.Length) + entryData.Length; if (entry.AESKeySize > 0) { this.offset += entry.AESOverheadSize; } this.curEntry = entry; this.crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { base.deflater_.Reset(); base.deflater_.SetLevel(defaultCompressionLevel); } this.size = 0L; if (entry.IsCrypted) { if (entry.AESKeySize > 0) { this.WriteAESHeader(entry); } else if (entry.Crc < 0L) { this.WriteEncryptionHeader(entry.DosTime << 0x10); } else { this.WriteEncryptionHeader(entry.Crc); } } }