GetEntryData() public method

Get the raw extra data value
public GetEntryData ( ) : byte[]
return byte[]
Exemplo n.º 1
0
 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);
         }
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Finishes the stream.  This will write the central directory at the
        /// end of the zip file and flush the stream.
        /// </summary>
        /// <remarks>
        /// This is automatically called when the stream is closed.
        /// </remarks>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurs.
        /// </exception>
        /// <exception cref="ZipException">
        /// Comment exceeds the maximum length<br/>
        /// Entry name exceeds the maximum length
        /// </exception>
        public override void Finish()
        {
            if (entries == null)
            {
                return;
            }

            if (curEntry != null)
            {
                CloseEntry();
            }

            long numEntries = entries.Count;
            long sizeEntries = 0;

            foreach (ZipEntry entry in entries)
            {
                WriteLeInt(ZipConstants.CentralHeaderSignature);
                WriteLeShort(ZipConstants.VersionMadeBy);
                WriteLeShort(entry.Version);
                WriteLeShort(entry.Flags);
                WriteLeShort((short) entry.CompressionMethodForHeader);
                WriteLeInt((int) entry.DosTime);
                WriteLeInt((int) entry.Crc);

                if (entry.IsZip64Forced() ||
                    (entry.CompressedSize >= uint.MaxValue))
                {
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt((int) entry.CompressedSize);
                }

                if (entry.IsZip64Forced() ||
                    (entry.Size >= uint.MaxValue))
                {
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt((int) entry.Size);
                }

                byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

                if (name.Length > 0xffff)
                {
                    throw new ZipException("Name too long.");
                }

                var ed = new ZipExtraData(entry.ExtraData);

                if (entry.CentralHeaderRequiresZip64)
                {
                    ed.StartNewEntry();
                    if (entry.IsZip64Forced() ||
                        (entry.Size >= 0xffffffff))
                    {
                        ed.AddLeLong(entry.Size);
                    }

                    if (entry.IsZip64Forced() ||
                        (entry.CompressedSize >= 0xffffffff))
                    {
                        ed.AddLeLong(entry.CompressedSize);
                    }

                    if (entry.Offset >= 0xffffffff)
                    {
                        ed.AddLeLong(entry.Offset);
                    }

                    ed.AddNewEntry(1);
                }
                else
                {
                    ed.Delete(1);
                }

#if !NET_1_1 && !NETCF_2_0
                if (entry.AESKeySize > 0)
                {
                    AddExtraDataAES(entry, ed);
                }
#endif
                byte[] extra = ed.GetEntryData();

                byte[] entryComment =
                    (entry.Comment != null)
                        ? ZipConstants.ConvertToArray(entry.Flags, entry.Comment)
                        : new byte[0];

                if (entryComment.Length > 0xffff)
                {
                    throw new ZipException("Comment too long.");
                }

                WriteLeShort(name.Length);
                WriteLeShort(extra.Length);
                WriteLeShort(entryComment.Length);
                WriteLeShort(0); // disk number
                WriteLeShort(0); // internal file attributes
                // external file attributes

                if (entry.ExternalFileAttributes != -1)
                {
                    WriteLeInt(entry.ExternalFileAttributes);
                }
                else
                {
                    if (entry.IsDirectory)
                    {
                        // mark entry as directory (from nikolam.AT.perfectinfo.com)
                        WriteLeInt(16);
                    }
                    else
                    {
                        WriteLeInt(0);
                    }
                }

                if (entry.Offset >= uint.MaxValue)
                {
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt((int) entry.Offset);
                }

                if (name.Length > 0)
                {
                    baseOutputStream_.Write(name, 0, name.Length);
                }

                if (extra.Length > 0)
                {
                    baseOutputStream_.Write(extra, 0, extra.Length);
                }

                if (entryComment.Length > 0)
                {
                    baseOutputStream_.Write(entryComment, 0, entryComment.Length);
                }

                sizeEntries += ZipConstants.CentralHeaderBaseSize + name.Length + extra.Length + entryComment.Length;
            }

            using (var zhs = new ZipHelperStream(baseOutputStream_))
            {
                zhs.WriteEndOfCentralDirectory(numEntries, sizeEntries, offset, zipComment);
            }

            entries = null;
        }
Exemplo n.º 3
0
		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);
			}
		}
Exemplo n.º 4
0
        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");
        }
Exemplo n.º 5
0
        public void PasswordCheckingWithDateInExtraData()
        {
            MemoryStream ms = new MemoryStream();
            DateTime checkTime = new DateTime(2010, 10, 16, 0, 3, 28);

            using (ZipOutputStream zos = new ZipOutputStream(ms)) {
                zos.IsStreamOwner = false;
                zos.Password = "******";
                ZipEntry ze = new ZipEntry("uno");
                ze.DateTime = new DateTime(1998, 6, 5, 4, 3, 2);

                ZipExtraData zed = new ZipExtraData();

                zed.StartNewEntry();

                zed.AddData(1);

                TimeSpan delta = checkTime.ToUniversalTime() - new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime();
                int seconds = (int)delta.TotalSeconds;
                zed.AddLeInt(seconds);
                zed.AddNewEntry(0x5455);

                ze.ExtraData = zed.GetEntryData();
                zos.PutNextEntry(ze);
                zos.WriteByte(54);
            }

            ms.Position = 0;
            using (ZipInputStream zis = new ZipInputStream(ms)) {
                zis.Password = "******";
                ZipEntry uno = zis.GetNextEntry();
                byte theByte = (byte)zis.ReadByte();
                Assert.AreEqual(54, theByte);
                Assert.AreEqual(-1, zis.ReadByte());
                Assert.AreEqual(checkTime, uno.DateTime);
            }
        }
Exemplo n.º 6
0
        public override void Finish()
        {
            if (this.entries == null)
            {
                return;
            }
            if (this.curEntry != null)
            {
                this.CloseEntry();
            }
            long noOfEntries = (long)this.entries.Count;
            long num         = 0L;

            foreach (ZipEntry zipEntry in this.entries)
            {
                this.WriteLeInt(33639248);
                this.WriteLeShort(51);
                this.WriteLeShort(zipEntry.Version);
                this.WriteLeShort(zipEntry.Flags);
                this.WriteLeShort((int)((short)zipEntry.CompressionMethodForHeader));
                this.WriteLeInt((int)zipEntry.DosTime);
                this.WriteLeInt((int)zipEntry.Crc);
                if (zipEntry.IsZip64Forced() || zipEntry.CompressedSize >= (long)((ulong)-1))
                {
                    this.WriteLeInt(-1);
                }
                else
                {
                    this.WriteLeInt((int)zipEntry.CompressedSize);
                }
                if (zipEntry.IsZip64Forced() || zipEntry.Size >= (long)((ulong)-1))
                {
                    this.WriteLeInt(-1);
                }
                else
                {
                    this.WriteLeInt((int)zipEntry.Size);
                }
                byte[] array = ZipConstants.ConvertToArray(zipEntry.Flags, zipEntry.Name);
                if (array.Length > 65535)
                {
                    throw new ZipException("Name too long.");
                }
                ZipExtraData zipExtraData = new ZipExtraData(zipEntry.ExtraData);
                if (zipEntry.CentralHeaderRequiresZip64)
                {
                    zipExtraData.StartNewEntry();
                    if (zipEntry.IsZip64Forced() || zipEntry.Size >= (long)((ulong)-1))
                    {
                        zipExtraData.AddLeLong(zipEntry.Size);
                    }
                    if (zipEntry.IsZip64Forced() || zipEntry.CompressedSize >= (long)((ulong)-1))
                    {
                        zipExtraData.AddLeLong(zipEntry.CompressedSize);
                    }
                    if (zipEntry.Offset >= (long)((ulong)-1))
                    {
                        zipExtraData.AddLeLong(zipEntry.Offset);
                    }
                    zipExtraData.AddNewEntry(1);
                }
                else
                {
                    zipExtraData.Delete(1);
                }
                if (zipEntry.AESKeySize > 0)
                {
                    ZipOutputStream.AddExtraDataAES(zipEntry, zipExtraData);
                }
                byte[] entryData = zipExtraData.GetEntryData();
                byte[] array2    = (zipEntry.Comment == null) ? new byte[0] : ZipConstants.ConvertToArray(zipEntry.Flags, zipEntry.Comment);
                if (array2.Length > 65535)
                {
                    throw new ZipException("Comment too long.");
                }
                this.WriteLeShort(array.Length);
                this.WriteLeShort(entryData.Length);
                this.WriteLeShort(array2.Length);
                this.WriteLeShort(0);
                this.WriteLeShort(0);
                if (zipEntry.ExternalFileAttributes != -1)
                {
                    this.WriteLeInt(zipEntry.ExternalFileAttributes);
                }
                else if (zipEntry.IsDirectory)
                {
                    this.WriteLeInt(16);
                }
                else
                {
                    this.WriteLeInt(0);
                }
                if (zipEntry.Offset >= (long)((ulong)-1))
                {
                    this.WriteLeInt(-1);
                }
                else
                {
                    this.WriteLeInt((int)zipEntry.Offset);
                }
                if (array.Length > 0)
                {
                    this.baseOutputStream_.Write(array, 0, array.Length);
                }
                if (entryData.Length > 0)
                {
                    this.baseOutputStream_.Write(entryData, 0, entryData.Length);
                }
                if (array2.Length > 0)
                {
                    this.baseOutputStream_.Write(array2, 0, array2.Length);
                }
                num += (long)(46 + array.Length + entryData.Length + array2.Length);
            }
            using (ZipHelperStream zipHelperStream = new ZipHelperStream(this.baseOutputStream_))
            {
                zipHelperStream.WriteEndOfCentralDirectory(noOfEntries, num, this.offset, this.zipComment);
            }
            this.entries = null;
        }
Exemplo n.º 7
0
        /// <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 && 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.");
            }

            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);
            }

#if !NET_1_1 && !NETCF_2_0 && !UNITY_WINRT
            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 && !UNITY_WINRT
                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);
                    }
                }
            }
        }
        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);
                }
            }
        }
Exemplo n.º 9
0
        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);
                }
            }
        }
Exemplo n.º 10
0
 public override void Finish()
 {
     if (entries != null)
     {
         if (curEntry != null)
         {
             CloseEntry();
         }
         long noOfEntries = entries.Count;
         long num         = 0L;
         foreach (ZipEntry entry in entries)
         {
             WriteLeInt(33639248);
             WriteLeShort(51);
             WriteLeShort(entry.Version);
             WriteLeShort(entry.Flags);
             WriteLeShort((short)entry.CompressionMethodForHeader);
             WriteLeInt((int)entry.DosTime);
             WriteLeInt((int)entry.Crc);
             if (entry.IsZip64Forced() || entry.CompressedSize >= uint.MaxValue)
             {
                 WriteLeInt(-1);
             }
             else
             {
                 WriteLeInt((int)entry.CompressedSize);
             }
             if (entry.IsZip64Forced() || entry.Size >= uint.MaxValue)
             {
                 WriteLeInt(-1);
             }
             else
             {
                 WriteLeInt((int)entry.Size);
             }
             byte[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
             if (array.Length > 65535)
             {
                 throw new ZipException("Name too long.");
             }
             ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData);
             if (entry.CentralHeaderRequiresZip64)
             {
                 zipExtraData.StartNewEntry();
                 if (entry.IsZip64Forced() || entry.Size >= uint.MaxValue)
                 {
                     zipExtraData.AddLeLong(entry.Size);
                 }
                 if (entry.IsZip64Forced() || entry.CompressedSize >= uint.MaxValue)
                 {
                     zipExtraData.AddLeLong(entry.CompressedSize);
                 }
                 if (entry.Offset >= uint.MaxValue)
                 {
                     zipExtraData.AddLeLong(entry.Offset);
                 }
                 zipExtraData.AddNewEntry(1);
             }
             else
             {
                 zipExtraData.Delete(1);
             }
             if (entry.AESKeySize > 0)
             {
                 AddExtraDataAES(entry, zipExtraData);
             }
             byte[] entryData = zipExtraData.GetEntryData();
             byte[] array2    = (entry.Comment != null) ? ZipConstants.ConvertToArray(entry.Flags, entry.Comment) : new byte[0];
             if (array2.Length > 65535)
             {
                 throw new ZipException("Comment too long.");
             }
             WriteLeShort(array.Length);
             WriteLeShort(entryData.Length);
             WriteLeShort(array2.Length);
             WriteLeShort(0);
             WriteLeShort(0);
             if (entry.ExternalFileAttributes != -1)
             {
                 WriteLeInt(entry.ExternalFileAttributes);
             }
             else if (entry.IsDirectory)
             {
                 WriteLeInt(16);
             }
             else
             {
                 WriteLeInt(0);
             }
             if (entry.Offset >= uint.MaxValue)
             {
                 WriteLeInt(-1);
             }
             else
             {
                 WriteLeInt((int)entry.Offset);
             }
             if (array.Length != 0)
             {
                 baseOutputStream_.Write(array, 0, array.Length);
             }
             if (entryData.Length != 0)
             {
                 baseOutputStream_.Write(entryData, 0, entryData.Length);
             }
             if (array2.Length != 0)
             {
                 baseOutputStream_.Write(array2, 0, array2.Length);
             }
             num += 46 + array.Length + entryData.Length + array2.Length;
         }
         using (ZipHelperStream zipHelperStream = new ZipHelperStream(baseOutputStream_))
         {
             zipHelperStream.WriteEndOfCentralDirectory(noOfEntries, num, offset, zipComment);
         }
         entries = null;
     }
 }
Exemplo n.º 11
0
        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);
                }
            }
        }
Exemplo n.º 12
0
 /// <summary>
 /// Encodes a <paramref name="timestamp"/> as a <see cref="ZipEntry.ExtraData"/> in a format that ensures it will be read for <see cref="ZipEntry.DateTime"/>, preserving second-accuracy.
 /// </summary>
 private static byte[] GetUnixTimestamp(DateTime timestamp)
 {
     var extraData = new ZipExtraData();
     extraData.AddEntry(new ExtendedUnixData
     {
         AccessTime = timestamp, CreateTime = timestamp, ModificationTime = timestamp,
         Include = ExtendedUnixData.Flags.AccessTime | ExtendedUnixData.Flags.CreateTime | ExtendedUnixData.Flags.ModificationTime
     });
     return extraData.GetEntryData();
 }
Exemplo n.º 13
0
        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);
            }
        }
Exemplo n.º 14
0
 private int WriteCentralDirectoryHeader(ZipEntry entry)
 {
     if (entry.CompressedSize < 0L)
     {
         throw new ZipException("Attempt to write central directory entry with unknown csize");
     }
     if (entry.Size < 0L)
     {
         throw new ZipException("Attempt to write central directory entry with unknown size");
     }
     if (entry.Crc < 0L)
     {
         throw new ZipException("Attempt to write central directory entry with unknown crc");
     }
     this.WriteLEInt(0x2014b50);
     this.WriteLEShort(0x33);
     this.WriteLEShort(entry.Version);
     this.WriteLEShort(entry.Flags);
     this.WriteLEShort((byte) entry.CompressionMethod);
     this.WriteLEInt((int) entry.DosTime);
     this.WriteLEInt((int) entry.Crc);
     if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
     {
         this.WriteLEInt(-1);
     }
     else
     {
         this.WriteLEInt((int) (((ulong) entry.CompressedSize) & 0xffffffffL));
     }
     if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
     {
         this.WriteLEInt(-1);
     }
     else
     {
         this.WriteLEInt((int) entry.Size);
     }
     byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
     if (buffer.Length > 0xffff)
     {
         throw new ZipException("Entry name is too long.");
     }
     this.WriteLEShort(buffer.Length);
     ZipExtraData data = new ZipExtraData(entry.ExtraData);
     if (entry.CentralHeaderRequiresZip64)
     {
         data.StartNewEntry();
         if ((entry.Size >= 0xffffffffL) || (this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.On))
         {
             data.AddLeLong(entry.Size);
         }
         if ((entry.CompressedSize >= 0xffffffffL) || (this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.On))
         {
             data.AddLeLong(entry.CompressedSize);
         }
         if (entry.Offset >= 0xffffffffL)
         {
             data.AddLeLong(entry.Offset);
         }
         data.AddNewEntry(1);
     }
     else
     {
         data.Delete(1);
     }
     byte[] entryData = data.GetEntryData();
     this.WriteLEShort(entryData.Length);
     this.WriteLEShort((entry.Comment != null) ? entry.Comment.Length : 0);
     this.WriteLEShort(0);
     this.WriteLEShort(0);
     if (entry.ExternalFileAttributes != -1)
     {
         this.WriteLEInt(entry.ExternalFileAttributes);
     }
     else if (entry.IsDirectory)
     {
         this.WriteLEUint(0x10);
     }
     else
     {
         this.WriteLEUint(0);
     }
     if (entry.Offset >= 0xffffffffL)
     {
         this.WriteLEUint(uint.MaxValue);
     }
     else
     {
         this.WriteLEUint((uint) ((int) entry.Offset));
     }
     if (buffer.Length > 0)
     {
         this.baseStream_.Write(buffer, 0, buffer.Length);
     }
     if (entryData.Length > 0)
     {
         this.baseStream_.Write(entryData, 0, entryData.Length);
     }
     byte[] buffer3 = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0];
     if (buffer3.Length > 0)
     {
         this.baseStream_.Write(buffer3, 0, buffer3.Length);
     }
     return (((0x2e + buffer.Length) + entryData.Length) + buffer3.Length);
 }
Exemplo n.º 15
0
        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);
                }
            }
        }
Exemplo n.º 16
0
        public override void Finish()
        {
            if (entries == null)
            {
                return;
            }
            if (curEntry != null)
            {
                CloseEntry();
            }
            long noOfEntries = entries.get_Count();
            long num         = 0L;

            global::System.Collections.IEnumerator enumerator = entries.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    ZipEntry zipEntry = (ZipEntry)enumerator.get_Current();
                    WriteLeInt(33639248);
                    WriteLeShort(51);
                    WriteLeShort(zipEntry.Version);
                    WriteLeShort(zipEntry.Flags);
                    WriteLeShort((short)zipEntry.CompressionMethodForHeader);
                    WriteLeInt((int)zipEntry.DosTime);
                    WriteLeInt((int)zipEntry.Crc);
                    if (zipEntry.IsZip64Forced() || zipEntry.CompressedSize >= 4294967295u)
                    {
                        WriteLeInt(-1);
                    }
                    else
                    {
                        WriteLeInt((int)zipEntry.CompressedSize);
                    }
                    if (zipEntry.IsZip64Forced() || zipEntry.Size >= 4294967295u)
                    {
                        WriteLeInt(-1);
                    }
                    else
                    {
                        WriteLeInt((int)zipEntry.Size);
                    }
                    byte[] array = ZipConstants.ConvertToArray(zipEntry.Flags, zipEntry.Name);
                    if (array.Length > 65535)
                    {
                        throw new ZipException("Name too long.");
                    }
                    ZipExtraData zipExtraData = new ZipExtraData(zipEntry.ExtraData);
                    if (zipEntry.CentralHeaderRequiresZip64)
                    {
                        zipExtraData.StartNewEntry();
                        if (zipEntry.IsZip64Forced() || zipEntry.Size >= 4294967295u)
                        {
                            zipExtraData.AddLeLong(zipEntry.Size);
                        }
                        if (zipEntry.IsZip64Forced() || zipEntry.CompressedSize >= 4294967295u)
                        {
                            zipExtraData.AddLeLong(zipEntry.CompressedSize);
                        }
                        if (zipEntry.Offset >= 4294967295u)
                        {
                            zipExtraData.AddLeLong(zipEntry.Offset);
                        }
                        zipExtraData.AddNewEntry(1);
                    }
                    else
                    {
                        zipExtraData.Delete(1);
                    }
                    byte[] entryData = zipExtraData.GetEntryData();
                    byte[] array2    = ((zipEntry.Comment != null) ? ZipConstants.ConvertToArray(zipEntry.Flags, zipEntry.Comment) : new byte[0]);
                    if (array2.Length > 65535)
                    {
                        throw new ZipException("Comment too long.");
                    }
                    WriteLeShort(array.Length);
                    WriteLeShort(entryData.Length);
                    WriteLeShort(array2.Length);
                    WriteLeShort(0);
                    WriteLeShort(0);
                    if (zipEntry.ExternalFileAttributes != -1)
                    {
                        WriteLeInt(zipEntry.ExternalFileAttributes);
                    }
                    else if (zipEntry.IsDirectory)
                    {
                        WriteLeInt(16);
                    }
                    else
                    {
                        WriteLeInt(0);
                    }
                    if (zipEntry.Offset >= 4294967295u)
                    {
                        WriteLeInt(-1);
                    }
                    else
                    {
                        WriteLeInt((int)zipEntry.Offset);
                    }
                    if (array.Length > 0)
                    {
                        baseOutputStream_.Write(array, 0, array.Length);
                    }
                    if (entryData.Length > 0)
                    {
                        baseOutputStream_.Write(entryData, 0, entryData.Length);
                    }
                    if (array2.Length > 0)
                    {
                        baseOutputStream_.Write(array2, 0, array2.Length);
                    }
                    num += 46 + array.Length + entryData.Length + array2.Length;
                }
            }
            finally
            {
                global::System.IDisposable disposable = enumerator as global::System.IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
            ZipHelperStream zipHelperStream = new ZipHelperStream(baseOutputStream_);

            try
            {
                zipHelperStream.WriteEndOfCentralDirectory(noOfEntries, num, offset, zipComment);
            }
            finally
            {
                ((global::System.IDisposable)zipHelperStream)?.Dispose();
            }
            entries = null;
        }
Exemplo n.º 17
0
        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);
                }
            }
        }
Exemplo n.º 18
0
        int WriteCentralDirectoryHeader(ZipEntry entry)
        {
            if ( entry.CompressedSize < 0 ) {
                throw new ZipException("Attempt to write central directory entry with unknown csize");
            }

            if ( entry.Size < 0 ) {
                throw new ZipException("Attempt to write central directory entry with unknown size");
            }

            if ( entry.Crc < 0 ) {
                throw new ZipException("Attempt to write central directory entry with unknown crc");
            }

            WriteLEInt(ZipConstants.CentralHeaderSignature);

            WriteLEShort(ZipConstants.VersionMadeBy);

            WriteLEShort(entry.Version);

            WriteLEShort(entry.Flags);

            unchecked {
                WriteLEShort((byte)entry.CompressionMethod);
                WriteLEInt((int)entry.DosTime);
                WriteLEInt((int)entry.Crc);
            }

            if ( (entry.IsZip64Forced()) || (entry.CompressedSize >= 0xffffffff) ) {
                WriteLEInt(-1);
            }
            else {
                WriteLEInt((int)(entry.CompressedSize & 0xffffffff));
            }

            if ( (entry.IsZip64Forced()) || (entry.Size >= 0xffffffff) ) {
                WriteLEInt(-1);
            }
            else {
                WriteLEInt((int)entry.Size);
            }

            byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

            if ( name.Length > 0xFFFF ) {
                throw new ZipException("Entry name is too long.");
            }

            WriteLEShort(name.Length);

            ZipExtraData ed = new ZipExtraData(entry.ExtraData);

            if ( entry.CentralHeaderRequiresZip64 ) {
                ed.StartNewEntry();

                if ( (entry.Size >= 0xffffffff) || (useZip64_ == UseZip64.On) )
                {
                    ed.AddLeLong(entry.Size);
                }

                if ( (entry.CompressedSize >= 0xffffffff) || (useZip64_ == UseZip64.On) )
                {
                    ed.AddLeLong(entry.CompressedSize);
                }

                if ( entry.Offset >= 0xffffffff ) {
                    ed.AddLeLong(entry.Offset);
                }

                ed.AddNewEntry(1);
            }
            else {
                ed.Delete(1);
            }

            byte[] centralExtraData = ed.GetEntryData();

            WriteLEShort(centralExtraData.Length);
            WriteLEShort(entry.Comment != null ? entry.Comment.Length : 0);

            WriteLEShort(0);
            WriteLEShort(0);

            if ( entry.ExternalFileAttributes != -1 ) {
                WriteLEInt(entry.ExternalFileAttributes);
            }
            else {
                if ( entry.IsDirectory ) {
                    WriteLEUint(16);
                }
                else {
                    WriteLEUint(0);
                }
            }

            if ( entry.Offset >= 0xffffffff ) {
                WriteLEUint(0xffffffff);
            }
            else {
                WriteLEUint((uint)(int)entry.Offset);
            }

            if ( name.Length > 0 ) {
                baseStream_.Write(name, 0, name.Length);
            }

            if ( centralExtraData.Length > 0 ) {
                baseStream_.Write(centralExtraData, 0, centralExtraData.Length);
            }

            byte[] rawComment = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0];

            if ( rawComment.Length > 0 ) {
                baseStream_.Write(rawComment, 0, rawComment.Length);
            }

            return ZipConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length;
        }
Exemplo n.º 19
0
        // Write the local file header
        // TODO: ZipHelperStream.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage
        private 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 == 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 (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 = ZipStrings.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 && (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);
            }
        }
Exemplo n.º 20
0
        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);
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Finishes the stream.  This will write the central directory at the
        /// end of the zip file and flush the stream.
        /// </summary>
        /// <remarks>
        /// This is automatically called when the stream is closed.
        /// </remarks>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurs.
        /// </exception>
        /// <exception cref="ZipException">
        /// Comment exceeds the maximum length<br/>
        /// Entry name exceeds the maximum length
        /// </exception>
        public override void Finish()
        {
            if (entries == null)
            {
                return;
            }

            if (curEntry != null)
            {
                CloseEntry();
            }

            long numEntries  = entries.Count;
            long sizeEntries = 0;

            foreach (ZipEntry entry in entries)
            {
                WriteLeInt(ZipConstants.CentralHeaderSignature);
                WriteLeShort(ZipConstants.VersionMadeBy);
                WriteLeShort(entry.Version);
                WriteLeShort(entry.Flags);
                WriteLeShort((short)entry.CompressionMethodForHeader);
                WriteLeInt((int)entry.DosTime);
                WriteLeInt((int)entry.Crc);

                if (entry.IsZip64Forced() ||
                    (entry.CompressedSize >= uint.MaxValue))
                {
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt((int)entry.CompressedSize);
                }

                if (entry.IsZip64Forced() ||
                    (entry.Size >= uint.MaxValue))
                {
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt((int)entry.Size);
                }

                byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

                if (name.Length > 0xffff)
                {
                    throw new ZipException("Name too long.");
                }

                ZipExtraData ed = new ZipExtraData(entry.ExtraData);

                if (entry.CentralHeaderRequiresZip64)
                {
                    ed.StartNewEntry();
                    if (entry.IsZip64Forced() ||
                        (entry.Size >= 0xffffffff))
                    {
                        ed.AddLeLong(entry.Size);
                    }

                    if (entry.IsZip64Forced() ||
                        (entry.CompressedSize >= 0xffffffff))
                    {
                        ed.AddLeLong(entry.CompressedSize);
                    }

                    if (entry.Offset >= 0xffffffff)
                    {
                        ed.AddLeLong(entry.Offset);
                    }

                    ed.AddNewEntry(1);
                }
                else
                {
                    ed.Delete(1);
                }

#if !NET_1_1 && !NETCF_2_0 && !UNITY_WINRT
                if (entry.AESKeySize > 0)
                {
                    AddExtraDataAES(entry, ed);
                }
#endif
                byte[] extra = ed.GetEntryData();

                byte[] entryComment =
                    (entry.Comment != null) ?
                    ZipConstants.ConvertToArray(entry.Flags, entry.Comment) :
                    new byte[0];

                if (entryComment.Length > 0xffff)
                {
                    throw new ZipException("Comment too long.");
                }

                WriteLeShort(name.Length);
                WriteLeShort(extra.Length);
                WriteLeShort(entryComment.Length);
                WriteLeShort(0);                        // disk number
                WriteLeShort(0);                        // internal file attributes
                // external file attributes

                if (entry.ExternalFileAttributes != -1)
                {
                    WriteLeInt(entry.ExternalFileAttributes);
                }
                else
                {
                    if (entry.IsDirectory)                                               // mark entry as directory (from nikolam.AT.perfectinfo.com)
                    {
                        WriteLeInt(16);
                    }
                    else
                    {
                        WriteLeInt(0);
                    }
                }

                if (entry.Offset >= uint.MaxValue)
                {
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt((int)entry.Offset);
                }

                if (name.Length > 0)
                {
                    baseOutputStream_.Write(name, 0, name.Length);
                }

                if (extra.Length > 0)
                {
                    baseOutputStream_.Write(extra, 0, extra.Length);
                }

                if (entryComment.Length > 0)
                {
                    baseOutputStream_.Write(entryComment, 0, entryComment.Length);
                }

                sizeEntries += ZipConstants.CentralHeaderBaseSize + name.Length + extra.Length + entryComment.Length;
            }

            using (ZipHelperStream zhs = new ZipHelperStream(baseOutputStream_)) {
                zhs.WriteEndOfCentralDirectory(numEntries, sizeEntries, offset, zipComment);
            }

            entries = null;
        }
Exemplo n.º 22
0
 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);
     }
 }
Exemplo n.º 23
0
        public void Deleting()
        {
            ZipExtraData zed = new ZipExtraData();
            Assert.AreEqual(0, zed.Length);

            // Tag 1 Totoal length 10
            zed.AddEntry(1, new byte[] { 10, 11, 12, 13, 14, 15 });
            Assert.AreEqual(10, zed.Length, "Length should be 10");
            Assert.AreEqual(10, zed.GetEntryData().Length, "Data length should be 10");

            // Tag 2 total length  9
            zed.AddEntry(2, new byte[] { 20, 21, 22, 23, 24 });
            Assert.AreEqual(19, zed.Length, "Length should be 19");
            Assert.AreEqual(19, zed.GetEntryData().Length, "Data length should be 19");

            // Tag 3 Total Length 6
            zed.AddEntry(3, new byte[] { 30, 31 });
            Assert.AreEqual(25, zed.Length, "Length should be 25");
            Assert.AreEqual(25, zed.GetEntryData().Length, "Data length should be 25");

            zed.Delete(2);
            Assert.AreEqual(16, zed.Length, "Length should be 16");
            Assert.AreEqual(16, zed.GetEntryData().Length, "Data length should be 16");

            // Tag 2 total length  9
            zed.AddEntry(2, new byte[] { 20, 21, 22, 23, 24 });
            Assert.AreEqual(25, zed.Length, "Length should be 25");
            Assert.AreEqual(25, zed.GetEntryData().Length, "Data length should be 25");

            zed.AddEntry(3, null);
            Assert.AreEqual(23, zed.Length, "Length should be 23");
            Assert.AreEqual(23, zed.GetEntryData().Length, "Data length should be 23");
        }
Exemplo n.º 24
0
        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);
            }
        }
Exemplo n.º 25
0
        /// <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);
                    }
                }
            }
        }
Exemplo n.º 26
0
        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);
            }
        }
        // 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);
            }
        }
Exemplo n.º 28
0
 public override void Finish()
 {
     if (this.entries != null)
     {
         if (this.curEntry != null)
         {
             this.CloseEntry();
         }
         long count       = this.entries.Count;
         long sizeEntries = 0L;
         foreach (ZipEntry entry in this.entries)
         {
             this.WriteLeInt(0x2014b50);
             this.WriteLeShort(0x33);
             this.WriteLeShort(entry.Version);
             this.WriteLeShort(entry.Flags);
             this.WriteLeShort((short)entry.CompressionMethodForHeader);
             this.WriteLeInt((int)entry.DosTime);
             this.WriteLeInt((int)entry.Crc);
             if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
             {
                 this.WriteLeInt(-1);
             }
             else
             {
                 this.WriteLeInt((int)entry.CompressedSize);
             }
             if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
             {
                 this.WriteLeInt(-1);
             }
             else
             {
                 this.WriteLeInt((int)entry.Size);
             }
             byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
             if (buffer.Length > 0xffff)
             {
                 throw new ZipException("Name too long.");
             }
             ZipExtraData extraData = new ZipExtraData(entry.ExtraData);
             if (entry.CentralHeaderRequiresZip64)
             {
                 extraData.StartNewEntry();
                 if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
                 {
                     extraData.AddLeLong(entry.Size);
                 }
                 if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
                 {
                     extraData.AddLeLong(entry.CompressedSize);
                 }
                 if (entry.Offset >= 0xffffffffL)
                 {
                     extraData.AddLeLong(entry.Offset);
                 }
                 extraData.AddNewEntry(1);
             }
             else
             {
                 extraData.Delete(1);
             }
             if (entry.AESKeySize > 0)
             {
                 AddExtraDataAES(entry, extraData);
             }
             byte[] entryData = extraData.GetEntryData();
             byte[] buffer3   = (entry.Comment != null) ? ZipConstants.ConvertToArray(entry.Flags, entry.Comment) : new byte[0];
             if (buffer3.Length > 0xffff)
             {
                 throw new ZipException("Comment too long.");
             }
             this.WriteLeShort(buffer.Length);
             this.WriteLeShort(entryData.Length);
             this.WriteLeShort(buffer3.Length);
             this.WriteLeShort(0);
             this.WriteLeShort(0);
             if (entry.ExternalFileAttributes != -1)
             {
                 this.WriteLeInt(entry.ExternalFileAttributes);
             }
             else if (entry.IsDirectory)
             {
                 this.WriteLeInt(0x10);
             }
             else
             {
                 this.WriteLeInt(0);
             }
             if (entry.Offset >= 0xffffffffL)
             {
                 this.WriteLeInt(-1);
             }
             else
             {
                 this.WriteLeInt((int)entry.Offset);
             }
             if (buffer.Length > 0)
             {
                 base.baseOutputStream_.Write(buffer, 0, buffer.Length);
             }
             if (entryData.Length > 0)
             {
                 base.baseOutputStream_.Write(entryData, 0, entryData.Length);
             }
             if (buffer3.Length > 0)
             {
                 base.baseOutputStream_.Write(buffer3, 0, buffer3.Length);
             }
             sizeEntries += ((0x2e + buffer.Length) + entryData.Length) + buffer3.Length;
         }
         using (ZipHelperStream stream = new ZipHelperStream(base.baseOutputStream_))
         {
             stream.WriteEndOfCentralDirectory(count, sizeEntries, this.offset, this.zipComment);
         }
         this.entries = null;
     }
 }
Exemplo n.º 29
0
		int WriteCentralDirectoryHeader(ZipEntry entry)
		{
			if ( entry.CompressedSize < 0 ) {
				throw new ZipException("Attempt to write central directory entry with unknown csize");
			}

			if ( entry.Size < 0 ) {
				throw new ZipException("Attempt to write central directory entry with unknown size");
			}
			
			if ( entry.Crc < 0 ) {
				throw new ZipException("Attempt to write central directory entry with unknown crc");
			}
			
			// Write the central file header
			WriteLEInt(ZipConstants.CentralHeaderSignature);

			// Version made by
			WriteLEShort(ZipConstants.VersionMadeBy);

			// Version required to extract
			WriteLEShort(entry.Version);

			WriteLEShort(entry.Flags);
			
			unchecked {
				WriteLEShort((byte)entry.CompressionMethod);
				WriteLEInt((int)entry.DosTime);
				WriteLEInt((int)entry.Crc);
			}

			if ( (entry.IsZip64Forced()) || (entry.CompressedSize >= 0xffffffff) ) {
				WriteLEInt(-1);
			}
			else {
				WriteLEInt((int)(entry.CompressedSize & 0xffffffff));
			}

			if ( (entry.IsZip64Forced()) || (entry.Size >= 0xffffffff) ) {
				WriteLEInt(-1);
			}
			else {
				WriteLEInt((int)entry.Size);
			}

			byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

			if ( name.Length > 0xFFFF ) {
				throw new ZipException("Entry name is too long.");
			}

			WriteLEShort(name.Length);

			// Central header extra data is different to local header version so regenerate.
			ZipExtraData ed = new ZipExtraData(entry.ExtraData);

			if ( entry.CentralHeaderRequiresZip64 ) {
				ed.StartNewEntry();

				if ( (entry.Size >= 0xffffffff) || (useZip64_ == UseZip64.On) )
				{
					ed.AddLeLong(entry.Size);
				}

				if ( (entry.CompressedSize >= 0xffffffff) || (useZip64_ == UseZip64.On) )
				{
					ed.AddLeLong(entry.CompressedSize);
				}

				if ( entry.Offset >= 0xffffffff ) {
					ed.AddLeLong(entry.Offset);
				}

				// Number of disk on which this file starts isnt supported and is never written here.
				ed.AddNewEntry(1);
			}
			else {
				// Should have already be done when local header was added.
				ed.Delete(1);
			}

			byte[] centralExtraData = ed.GetEntryData();

			WriteLEShort(centralExtraData.Length);
			WriteLEShort(entry.Comment != null ? entry.Comment.Length : 0);

			WriteLEShort(0);	// disk number
			WriteLEShort(0);	// internal file attributes

			// External file attributes...
			if ( entry.ExternalFileAttributes != -1 ) {
				WriteLEInt(entry.ExternalFileAttributes);
			}
			else {
				if ( entry.IsDirectory ) {
					WriteLEUint(16);
				}
				else {
					WriteLEUint(0);
				}
			}

			if ( entry.Offset >= 0xffffffff ) {
				WriteLEUint(0xffffffff);
			}
			else {
				WriteLEUint((uint)(int)entry.Offset);
			}

			if ( name.Length > 0 ) {
				baseStream_.Write(name, 0, name.Length);
			}

			if ( centralExtraData.Length > 0 ) {
				baseStream_.Write(centralExtraData, 0, centralExtraData.Length);
			}

			byte[] rawComment = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0];

			if ( rawComment.Length > 0 ) {
				baseStream_.Write(rawComment, 0, rawComment.Length);
			}

			return ZipConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length;
		}
Exemplo n.º 30
0
 public override void Finish()
 {
     if (this.entries != null)
     {
         if (this.curEntry != null)
         {
             this.CloseEntry();
         }
         long count = this.entries.Count;
         long sizeEntries = 0L;
         foreach (ZipEntry entry in this.entries)
         {
             this.WriteLeInt(0x2014b50);
             this.WriteLeShort(0x33);
             this.WriteLeShort(entry.Version);
             this.WriteLeShort(entry.Flags);
             this.WriteLeShort((short) entry.CompressionMethodForHeader);
             this.WriteLeInt((int) entry.DosTime);
             this.WriteLeInt((int) entry.Crc);
             if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
             {
                 this.WriteLeInt(-1);
             }
             else
             {
                 this.WriteLeInt((int) entry.CompressedSize);
             }
             if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
             {
                 this.WriteLeInt(-1);
             }
             else
             {
                 this.WriteLeInt((int) entry.Size);
             }
             byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
             if (buffer.Length > 0xffff)
             {
                 throw new ZipException("Name too long.");
             }
             ZipExtraData extraData = new ZipExtraData(entry.ExtraData);
             if (entry.CentralHeaderRequiresZip64)
             {
                 extraData.StartNewEntry();
                 if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
                 {
                     extraData.AddLeLong(entry.Size);
                 }
                 if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
                 {
                     extraData.AddLeLong(entry.CompressedSize);
                 }
                 if (entry.Offset >= 0xffffffffL)
                 {
                     extraData.AddLeLong(entry.Offset);
                 }
                 extraData.AddNewEntry(1);
             }
             else
             {
                 extraData.Delete(1);
             }
             if (entry.AESKeySize > 0)
             {
                 AddExtraDataAES(entry, extraData);
             }
             byte[] entryData = extraData.GetEntryData();
             byte[] buffer3 = (entry.Comment != null) ? ZipConstants.ConvertToArray(entry.Flags, entry.Comment) : new byte[0];
             if (buffer3.Length > 0xffff)
             {
                 throw new ZipException("Comment too long.");
             }
             this.WriteLeShort(buffer.Length);
             this.WriteLeShort(entryData.Length);
             this.WriteLeShort(buffer3.Length);
             this.WriteLeShort(0);
             this.WriteLeShort(0);
             if (entry.ExternalFileAttributes != -1)
             {
                 this.WriteLeInt(entry.ExternalFileAttributes);
             }
             else if (entry.IsDirectory)
             {
                 this.WriteLeInt(0x10);
             }
             else
             {
                 this.WriteLeInt(0);
             }
             if (entry.Offset >= 0xffffffffL)
             {
                 this.WriteLeInt(-1);
             }
             else
             {
                 this.WriteLeInt((int) entry.Offset);
             }
             if (buffer.Length > 0)
             {
                 base.baseOutputStream_.Write(buffer, 0, buffer.Length);
             }
             if (entryData.Length > 0)
             {
                 base.baseOutputStream_.Write(entryData, 0, entryData.Length);
             }
             if (buffer3.Length > 0)
             {
                 base.baseOutputStream_.Write(buffer3, 0, buffer3.Length);
             }
             sizeEntries += ((0x2e + buffer.Length) + entryData.Length) + buffer3.Length;
         }
         using (ZipHelperStream stream = new ZipHelperStream(base.baseOutputStream_))
         {
             stream.WriteEndOfCentralDirectory(count, sizeEntries, this.offset, this.zipComment);
         }
         this.entries = null;
     }
 }