A class to handle the extra data field for Zip entries
Extra data contains 0 or more values each prefixed by a header tag and length. They contain zero or more bytes of actual data. The data is held internally using a copy on write strategy. This is more efficient but means that for extra data created by passing in data can have the values modified by the caller in some circumstances.
Inheritance: IDisposable
 private static void AddExtraDataAES(ZipEntry entry, ZipExtraData extraData)
 {
     extraData.StartNewEntry();
     extraData.AddLeShort(2);
     extraData.AddLeShort(0x4541);
     extraData.AddData(entry.AESEncryptionStrength);
     extraData.AddLeShort((int) entry.CompressionMethod);
     extraData.AddNewEntry(0x9901);
 }
Beispiel #2
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();
 }
Beispiel #3
0
        private static void AddExtraDataAES(ZipEntry entry, ZipExtraData extraData)
        {
            // Vendor Version: AE-1 IS 1. AE-2 is 2. With AE-2 no CRC is required and 0 is stored.
            const int VENDOR_VERSION = 2;
            // Vendor ID is the two ASCII characters "AE".
            const int VENDOR_ID = 0x4541;             //not 6965;

            extraData.StartNewEntry();
            // Pack AES extra data field see http://www.winzip.com/aes_info.htm
            //extraData.AddLeShort(7);							// Data size (currently 7)
            extraData.AddLeShort(VENDOR_VERSION);                           // 2 = AE-2
            extraData.AddLeShort(VENDOR_ID);                                // "AE"
            extraData.AddData(entry.AESEncryptionStrength);                 //  1 = 128, 2 = 192, 3 = 256
            extraData.AddLeShort((int)entry.CompressionMethod);             // The actual compression method used to compress the file
            extraData.AddNewEntry(0x9901);
        }
Beispiel #4
0
        private DateTime GetDateTime(ZipExtraData extraData)
        {
            ExtendedUnixData data = extraData.GetData <ExtendedUnixData>();

            if (data != null && (byte)(data.Include & ExtendedUnixData.Flags.ModificationTime) != 0 && (byte)(data.Include & ExtendedUnixData.Flags.AccessTime) != 0 && (byte)(data.Include & ExtendedUnixData.Flags.CreateTime) != 0)
            {
                return(data.ModificationTime);
            }
            uint second = Math.Min(59u, 2u * (this.dosTime & 31u));
            uint minute = Math.Min(59u, this.dosTime >> 5 & 63u);
            uint hour   = Math.Min(23u, this.dosTime >> 11 & 31u);
            uint month  = Math.Max(1u, Math.Min(12u, this.dosTime >> 21 & 15u));
            uint year   = (this.dosTime >> 25 & 127u) + 1980u;
            int  day    = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)month), (int)(this.dosTime >> 16 & 31u)));

            return(new DateTime((int)year, (int)month, day, (int)hour, (int)minute, (int)second, DateTimeKind.Utc));
        }
Beispiel #5
0
        private DateTime GetDateTime(ZipExtraData extraData)
        {
            ExtendedUnixData data = extraData.GetData <ExtendedUnixData>();

            if (data != null && (data.Include & ExtendedUnixData.Flags.ModificationTime) != 0 && (data.Include & ExtendedUnixData.Flags.AccessTime) != 0 && (data.Include & ExtendedUnixData.Flags.CreateTime) != 0)
            {
                return(data.ModificationTime);
            }
            uint second = Math.Min(59u, 2 * (dosTime & 0x1F));
            uint minute = Math.Min(59u, (dosTime >> 5) & 0x3F);
            uint hour   = Math.Min(23u, (dosTime >> 11) & 0x1F);
            uint month  = Math.Max(1u, Math.Min(12u, (dosTime >> 21) & 0xF));
            uint year   = ((dosTime >> 25) & 0x7F) + 1980;
            int  day    = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)month), (int)((dosTime >> 16) & 0x1F)));

            return(new DateTime((int)year, (int)month, day, (int)hour, (int)minute, (int)second, DateTimeKind.Utc));
        }
Beispiel #6
0
        private static DateTime?GetDateTime(ZipExtraData extraData)
        {
            // Check for NT timestamp
            // NOTE: Disable by default to match behavior of InfoZIP
#if RESPECT_NT_TIMESTAMP
            NTTaggedData ntData = extraData.GetData <NTTaggedData>();
            if (ntData != null)
            {
                return(ntData.LastModificationTime);
            }
#endif

            // Check for Unix timestamp
            ExtendedUnixData unixData = extraData.GetData <ExtendedUnixData>();
            if (unixData != null && unixData.Include.HasFlag(ExtendedUnixData.Flags.ModificationTime))
            {
                return(unixData.ModificationTime);
            }

            return(null);
        }
Beispiel #7
0
        private void ProcessAESExtraData(ZipExtraData extraData)
        {
            if (!extraData.Find(39169))
            {
                throw new Exception("AES Extra Data missing");
            }
            this.versionToExtract = 51;
            this.Flags           |= 64;
            int valueLength = extraData.ValueLength;

            if (valueLength < 7)
            {
                throw new Exception("AES Extra Data Length " + valueLength + " invalid.");
            }
            extraData.ReadShort();
            extraData.ReadShort();
            extraData.ReadByte();
            int num = extraData.ReadShort();

            this.method = (CompressionMethod)num;
        }
Beispiel #8
0
 private void ProcessAESExtraData(ZipExtraData extraData)
 {
     if (extraData.Find(39169))
     {
         versionToExtract = 51;
         Flags           |= 64;
         int valueLength = extraData.ValueLength;
         if (valueLength < 7)
         {
             throw new ZipException("AES Extra Data Length " + valueLength + " invalid.");
         }
         int aesVer = extraData.ReadShort();
         extraData.ReadShort();
         int aesEncryptionStrength = extraData.ReadByte();
         int num = extraData.ReadShort();
         _aesVer = aesVer;
         _aesEncryptionStrength = aesEncryptionStrength;
         method = (CompressionMethod)num;
         return;
     }
     throw new ZipException("AES Extra Data missing");
 }
Beispiel #9
0
        private void ProcessAESExtraData(ZipExtraData extraData)
        {
            if (!extraData.Find(0x9901))
            {
                throw new ZipException("AES Extra Data missing");
            }
            this.versionToExtract = 0x33;
            this.Flags           |= 0x40;
            int valueLength = extraData.ValueLength;

            if (valueLength < 7)
            {
                throw new ZipException("AES Extra Data Length " + valueLength + " invalid.");
            }
            int num2 = extraData.ReadShort();
            int num3 = extraData.ReadShort();
            int num4 = extraData.ReadByte();
            int num5 = extraData.ReadShort();

            this._aesVer = num2;
            this._aesEncryptionStrength = num4;
            this.method = (ICSharpCode.SharpZipLib.Zip.CompressionMethod)num5;
        }
        // For AES the method in the entry is 99, and the real compression method is in the extradata
        //
        private void ProcessAESExtraData(ZipExtraData extraData)
        {
            if (extraData.Find(0x9901))
            {
                // Set version and flag for Zipfile.CreateAndInitDecryptionStream
                versionToExtract = ZipConstants.VERSION_AES;                            // Ver 5.1 = AES see "Version" getter
                // Set StrongEncryption flag for ZipFile.CreateAndInitDecryptionStream
                Flags = Flags | (int)GeneralBitFlags.StrongEncryption;
                //
                // Unpack AES extra data field see http://www.winzip.com/aes_info.htm
                int length = extraData.ValueLength;                         // Data size currently 7
//				if (length < 7)
                //throw new ZipException("AES Extra Data Length " + length + " invalid.");
                int ver            = extraData.ReadShort();                 // Version number (1=AE-1 2=AE-2)
                int vendorId       = extraData.ReadShort();                 // 2-character vendor ID 0x4541 = "AE"
                int encrStrength   = extraData.ReadByte();                  // encryption strength 1 = 128 2 = 192 3 = 256
                int actualCompress = extraData.ReadShort();                 // The actual compression method used to compress the file
                _aesVer = ver;
                _aesEncryptionStrength = encrStrength;
                method = (CompressionMethod)actualCompress;
            }
//			else
            //throw new ZipException("AES Extra Data missing");
        }
Beispiel #11
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);
            }
        }
Beispiel #12
0
        public void Skipping()
        {
            ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 });
            Assert.AreEqual(11, zed.Length, "Length should be 11");
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            Assert.AreEqual(7, zed.UnreadCount);
            Assert.AreEqual(4, zed.CurrentReadIndex);

            zed.ReadByte();
            Assert.AreEqual(6, zed.UnreadCount);
            Assert.AreEqual(5, zed.CurrentReadIndex);

            zed.Skip(1);
            Assert.AreEqual(5, zed.UnreadCount);
            Assert.AreEqual(6, zed.CurrentReadIndex);

            zed.Skip(-1);
            Assert.AreEqual(6, zed.UnreadCount);
            Assert.AreEqual(5, zed.CurrentReadIndex);

            zed.Skip(6);
            Assert.AreEqual(0, zed.UnreadCount);
            Assert.AreEqual(11, zed.CurrentReadIndex);

            bool exceptionCaught = false;

            try {
                zed.Skip(1);
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Should fail to skip past end");

            Assert.AreEqual(0, zed.UnreadCount);
            Assert.AreEqual(11, zed.CurrentReadIndex);

            zed.Skip(-7);
            Assert.AreEqual(7, zed.UnreadCount);
            Assert.AreEqual(4, zed.CurrentReadIndex);

            exceptionCaught=false;
            try
            {
                zed.Skip(-1);
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Should fail to skip before beginning");
        }
Beispiel #13
0
        public void ReadOverrunLong()
        {
            ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 });
            Assert.AreEqual(4, zed.Length, "Length should be 4");
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            // Empty Tag
            bool exceptionCaught = false;
            try {
                zed.ReadLong();
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");

            // seven bytes
            zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            exceptionCaught = false;
            try {
                zed.ReadLong();
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");

            zed = new ZipExtraData(new byte[] { 1, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            zed.ReadLong();

            exceptionCaught = false;
            try {
                zed.ReadLong();
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");
        }
Beispiel #14
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");
        }
Beispiel #15
0
		/// <summary>
		/// Test a local header against that provided from the central directory
		/// </summary>
		/// <param name="entry">
		/// The entry to test against
		/// </param>
		/// <param name="tests">The type of <see cref="HeaderTest">tests</see> to carry out.</param>
		/// <returns>The offset of the entries data in the file</returns>
		long TestLocalHeader(ZipEntry entry, HeaderTest tests)
		{
			lock(baseStream_) 
			{
				bool testHeader = (tests & HeaderTest.Header) != 0;
				bool testData = (tests & HeaderTest.Extract) != 0;

				baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin);
				if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) {
					throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset));
				}

				short extractVersion = ( short ) (ReadLEUshort() & 0x00ff);
				short localFlags = ( short )ReadLEUshort();
				short compressionMethod = ( short )ReadLEUshort();
				short fileTime = ( short )ReadLEUshort();
				short fileDate = ( short )ReadLEUshort();
				uint crcValue = ReadLEUint();
				long compressedSize = ReadLEUint();
				long size = ReadLEUint();
				int storedNameLength = ReadLEUshort();
				int extraDataLength = ReadLEUshort();

				byte[] nameData = new byte[storedNameLength];
				StreamUtils.ReadFully(baseStream_, nameData);

				byte[] extraData = new byte[extraDataLength];
				StreamUtils.ReadFully(baseStream_, extraData);

				ZipExtraData localExtraData = new ZipExtraData(extraData);

				// Extra data / zip64 checks
				if (localExtraData.Find(1))
				{
					// 2010-03-04 Forum 10512: removed checks for version >= ZipConstants.VersionZip64
					// and size or compressedSize = MaxValue, due to rogue creators.

					size = localExtraData.ReadLong();
					compressedSize = localExtraData.ReadLong();

                    if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0)
                    {
                        // These may be valid if patched later
                        if ( (size != -1) && (size != entry.Size)) {
                            throw new ZipException("Size invalid for descriptor");
                        }

                        if ((compressedSize != -1) && (compressedSize != entry.CompressedSize)) {
                            throw new ZipException("Compressed size invalid for descriptor");
                        }
                    }
                }
				else
				{
					// No zip64 extra data but entry requires it.
					if ((extractVersion >= ZipConstants.VersionZip64) &&
						(((uint)size == uint.MaxValue) || ((uint)compressedSize == uint.MaxValue)))
					{
						throw new ZipException("Required Zip64 extended information missing");
					}
				}

				if ( testData ) {
					if ( entry.IsFile ) {
						if ( !entry.IsCompressionMethodSupported() ) {
							throw new ZipException("Compression method not supported");
						}

						if ( (extractVersion > ZipConstants.VersionMadeBy)
							|| ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64)) ) {
							throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion));
						}

						if ( (localFlags & ( int )(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0 ) {
							throw new ZipException("The library does not support the zip version required to extract this entry");
						}
					}
				}

                if (testHeader)
                {
                    if ((extractVersion <= 63) &&	// Ignore later versions as we dont know about them..
                        (extractVersion != 10) &&
                        (extractVersion != 11) &&
                        (extractVersion != 20) &&
                        (extractVersion != 21) &&
                        (extractVersion != 25) &&
                        (extractVersion != 27) &&
                        (extractVersion != 45) &&
                        (extractVersion != 46) &&
                        (extractVersion != 50) &&
                        (extractVersion != 51) &&
                        (extractVersion != 52) &&
                        (extractVersion != 61) &&
                        (extractVersion != 62) &&
                        (extractVersion != 63)
                        )
                    {
                        throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion));
                    }

                    // Local entry flags dont have reserved bit set on.
                    if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0)
                    {
                        throw new ZipException("Reserved bit flags cannot be set.");
                    }

                    // Encryption requires extract version >= 20
                    if (((localFlags & (int)GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20))
                    {
                        throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion));
                    }

                    // Strong encryption requires encryption flag to be set and extract version >= 50.
                    if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0)
                    {
                        if ((localFlags & (int)GeneralBitFlags.Encrypted) == 0)
                        {
                            throw new ZipException("Strong encryption flag set but encryption flag is not set");
                        }

                        if (extractVersion < 50)
                        {
                            throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion));
                        }
                    }

                    // Patched entries require extract version >= 27
                    if (((localFlags & (int)GeneralBitFlags.Patched) != 0) && (extractVersion < 27))
                    {
                        throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion));
                    }

                    // Central header flags match local entry flags.
                    if (localFlags != entry.Flags)
                    {
                        throw new ZipException("Central header/local header flags mismatch");
                    }

                    // Central header compression method matches local entry
                    if (entry.CompressionMethod != (CompressionMethod)compressionMethod)
                    {
                        throw new ZipException("Central header/local header compression method mismatch");
                    }

                    if (entry.Version != extractVersion)
                    {
                        throw new ZipException("Extract version mismatch");
                    }

                    // Strong encryption and extract version match
                    if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0)
                    {
                        if (extractVersion < 62)
                        {
                            throw new ZipException("Strong encryption flag set but version not high enough");
                        }
                    }

                    if ((localFlags & (int)GeneralBitFlags.HeaderMasked) != 0)
                    {
                        if ((fileTime != 0) || (fileDate != 0))
                        {
                            throw new ZipException("Header masked set but date/time values non-zero");
                        }
                    }

                    if ((localFlags & (int)GeneralBitFlags.Descriptor) == 0)
                    {
                        if (crcValue != (uint)entry.Crc)
                        {
                            throw new ZipException("Central header/local header crc mismatch");
                        }
                    }

                    // Crc valid for empty entry.
                    // This will also apply to streamed entries where size isnt known and the header cant be patched
                    if ((size == 0) && (compressedSize == 0))
                    {
                        if (crcValue != 0)
                        {
                            throw new ZipException("Invalid CRC for empty entry");
                        }
                    }

                    // TODO: make test more correct...  can't compare lengths as was done originally as this can fail for MBCS strings
                    // Assuming a code page at this point is not valid?  Best is to store the name length in the ZipEntry probably
                    if (entry.Name.Length > storedNameLength)
                    {
                        throw new ZipException("File name length mismatch");
                    }

                    // Name data has already been read convert it and compare.
                    string localName = ZipConstants.ConvertToStringExt(localFlags, nameData);

                    // Central directory and local entry name match
                    if (localName != entry.Name)
                    {
                        throw new ZipException("Central header and local header file name mismatch");
                    }

                    // Directories have zero actual size but can have compressed size
                    if (entry.IsDirectory)
                    {
                        if (size > 0)
                        {
                            throw new ZipException("Directory cannot have size");
                        }

                        // There may be other cases where the compressed size can be greater than this?
                        // If so until details are known we will be strict.
                        if (entry.IsCrypted)
                        {
                            if (compressedSize > ZipConstants.CryptoHeaderSize + 2)
                            {
                                throw new ZipException("Directory compressed size invalid");
                            }
                        }
                        else if (compressedSize > 2)
                        {
                            // When not compressed the directory size can validly be 2 bytes
                            // if the true size wasnt known when data was originally being written.
                            // NOTE: Versions of the library 0.85.4 and earlier always added 2 bytes
                            throw new ZipException("Directory compressed size invalid");
                        }
                    }

                    if (!ZipNameTransform.IsValidName(localName, true))
                    {
                        throw new ZipException("Name is invalid");
                    }
                }

				// Tests that apply to both data and header.

				// Size can be verified only if it is known in the local header.
				// it will always be known in the central header.
				if (((localFlags & (int)GeneralBitFlags.Descriptor) == 0) ||
					((size > 0 || compressedSize > 0) && entry.Size > 0)) {

					if ((size != 0)
						&& (size != entry.Size)) {
						throw new ZipException(
							string.Format("Size mismatch between central header({0}) and local header({1})",
								entry.Size, size));
					}

					if ((compressedSize != 0)
						&& (compressedSize != entry.CompressedSize && compressedSize != 0xFFFFFFFF && compressedSize != -1)) {
						throw new ZipException(
							string.Format("Compressed size mismatch between central header({0}) and local header({1})",
							entry.CompressedSize, compressedSize));
					}
				}

				int extraLength = storedNameLength + extraDataLength;
				return offsetOfFirstEntry + entry.Offset + ZipConstants.LocalHeaderBaseSize + extraLength;
			}
		}
Beispiel #16
0
        /// <summary>
        /// Process extra data fields updating the entry based on the contents.
        /// </summary>
        /// <param name="localHeader">True if the extra data fields should be handled
        /// for a local header, rather than for a central header.
        /// </param>
        internal void ProcessExtraData(bool localHeader)
        {
            ZipExtraData extraData = new ZipExtraData(this.extra);

            if (extraData.Find(0x0001))
            {
                // Version required to extract is ignored here as some archivers dont set it correctly
                // in theory it should be version 45 or higher

                // The recorded size will change but remember that this is zip64.
                forceZip64_ = true;

                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }

                if (localHeader || (size == uint.MaxValue))
                {
                    size = (ulong)extraData.ReadLong();
                }

                if (localHeader || (compressedSize == uint.MaxValue))
                {
                    compressedSize = (ulong)extraData.ReadLong();
                }

                if (!localHeader && (offset == uint.MaxValue))
                {
                    offset = extraData.ReadLong();
                }

                // Disk number on which file starts is ignored
            }
            else
            {
                if (
                    ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
                    ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
                    )
                {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }

            if (extraData.Find(10))
            {
                // No room for any tags.
                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("NTFS Extra data invalid");
                }

                extraData.ReadInt(); // Reserved

                while (extraData.UnreadCount >= 4)
                {
                    int ntfsTag    = extraData.ReadShort();
                    int ntfsLength = extraData.ReadShort();
                    if (ntfsTag == 1)
                    {
                        if (ntfsLength >= 24)
                        {
                            long lastModification = extraData.ReadLong();
                            long lastAccess       = extraData.ReadLong();
                            long createTime       = extraData.ReadLong();

                            DateTime = System.DateTime.FromFileTime(lastModification);
                        }
                        break;
                    }
                    else
                    {
                        // An unknown NTFS tag so simply skip it.
                        extraData.Skip(ntfsLength);
                    }
                }
            }
            else if (extraData.Find(0x5455))
            {
                int length = extraData.ValueLength;
                int flags  = extraData.ReadByte();

                // Can include other times but these are ignored.  Length of data should
                // actually be 1 + 4 * no of bits in flags.
                if (((flags & 1) != 0) && (length >= 5))
                {
                    int iTime = extraData.ReadInt();

                    DateTime = (new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() +
                                new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime();
                }
            }
            if (method == CompressionMethod.WinZipAES)
            {
                ProcessAESExtraData(extraData);
            }
        }
Beispiel #17
0
        internal void ProcessExtraData(bool localHeader)
        {
            ZipExtraData zipExtraData = new ZipExtraData(this.extra);

            if (zipExtraData.Find(1))
            {
                this.forceZip64_ = true;
                if (zipExtraData.ValueLength < 4)
                {
                    throw new Exception("Extra data extended Zip64 information length is invalid");
                }
                if (localHeader || this.size == (ulong)-1)
                {
                    this.size = (ulong)zipExtraData.ReadLong();
                }
                if (localHeader || this.compressedSize == (ulong)-1)
                {
                    this.compressedSize = (ulong)zipExtraData.ReadLong();
                }
                if (!localHeader && this.offset == (long)((ulong)-1))
                {
                    this.offset = zipExtraData.ReadLong();
                }
            }
            else if ((this.versionToExtract & 255) >= 45 && (this.size == (ulong)-1 || this.compressedSize == (ulong)-1))
            {
                throw new Exception("Zip64 Extended information required but is missing.");
            }
            if (zipExtraData.Find(10))
            {
                if (zipExtraData.ValueLength < 4)
                {
                    throw new Exception("NTFS Extra data invalid");
                }
                zipExtraData.ReadInt();
                while (zipExtraData.UnreadCount >= 4)
                {
                    int num  = zipExtraData.ReadShort();
                    int num2 = zipExtraData.ReadShort();
                    if (num == 1)
                    {
                        if (num2 >= 24)
                        {
                            long fileTime = zipExtraData.ReadLong();
                            zipExtraData.ReadLong();
                            zipExtraData.ReadLong();
                            this.DateTime = DateTime.FromFileTime(fileTime);
                        }
                        break;
                    }
                    zipExtraData.Skip(num2);
                }
            }
            else if (zipExtraData.Find(21589))
            {
                int valueLength = zipExtraData.ValueLength;
                int num3        = zipExtraData.ReadByte();
                if ((num3 & 1) != 0 && valueLength >= 5)
                {
                    int      seconds  = zipExtraData.ReadInt();
                    DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0);
                    this.DateTime = (dateTime.ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime();
                }
            }
            if (this.method == CompressionMethod.WinZipAES)
            {
                this.ProcessAESExtraData(zipExtraData);
            }
        }
Beispiel #18
0
        internal void ProcessExtraData(bool localHeader)
        {
            ZipExtraData extraData = new ZipExtraData(this.extra);

            if (extraData.Find(0x0001))
            {
                if ((versionToExtract & 0xff) < ZipConstants.VersionZip64)
                {
                    throw new ZipException("Zip64 Extended information found but version is not valid");
                }

                forceZip64_ = true;

                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }

                if (localHeader || (size == uint.MaxValue))
                {
                    size = (ulong)extraData.ReadLong();
                }

                if (localHeader || (compressedSize == uint.MaxValue))
                {
                    compressedSize = (ulong)extraData.ReadLong();
                }

                if (!localHeader && (offset == uint.MaxValue))
                {
                    offset = extraData.ReadLong();
                }
            }
            else
            {
                if (
                    ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
                    ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
                    )
                {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }

            if (extraData.Find(10))
            {
                if (extraData.ValueLength < 8)
                {
                    throw new ZipException("NTFS Extra data invalid");
                }

                extraData.ReadInt();

                while (extraData.UnreadCount >= 4)
                {
                    int ntfsTag    = extraData.ReadShort();
                    int ntfsLength = extraData.ReadShort();
                    if (ntfsTag == 1)
                    {
                        if (ntfsLength >= 24)
                        {
                            long lastModification = extraData.ReadLong();
                            long lastAccess       = extraData.ReadLong();
                            long createTime       = extraData.ReadLong();

                            DateTime = System.DateTime.FromFileTime(lastModification);
                        }
                        break;
                    }
                    else
                    {
                        extraData.Skip(ntfsLength);
                    }
                }
            }
            else if (extraData.Find(0x5455))
            {
                int length = extraData.ValueLength;
                int flags  = extraData.ReadByte();

                if (((flags & 1) != 0) && (length >= 5))
                {
                    int iTime = extraData.ReadInt();

                    DateTime = (new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() +
                                new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime();
                }
            }
        }
Beispiel #19
0
 // For AES the method in the entry is 99, and the real compression method is in the extradata
 //
 private void ProcessAESExtraData(ZipExtraData extraData)
 {
     throw new ZipException("AES unsupported");
 }
Beispiel #20
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;
        }
Beispiel #21
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);
     }
 }
Beispiel #22
0
        public void ReadOverrunInt()
        {
            var zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 });
            Assert.AreEqual(4, zed.Length, "Length should be 4");
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            // Empty Tag
            bool exceptionCaught = false;
            try {
                zed.ReadInt();
            } catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");

            // three bytes
            zed = new ZipExtraData(new byte[] { 1, 0, 3, 0, 1, 2, 3 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            exceptionCaught = false;
            try {
                zed.ReadInt();
            } catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");

            zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            zed.ReadInt();

            exceptionCaught = false;
            try {
                zed.ReadInt();
            } catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");
        }
Beispiel #23
0
        /// <summary>
        /// Test a local header against that provided from the central directory
        /// </summary>
        /// <param name="entry">
        /// The entry to test against
        /// </param>
        /// <param name="tests">The type of <see cref="HeaderTest">tests</see> to carry out.</param>
        /// <returns>The offset of the entries data in the file</returns>
        long TestLocalHeader(ZipEntry entry, HeaderTest tests)
        {
            lock(baseStream_)
            {
                bool testHeader = (tests & HeaderTest.Header) != 0;
                bool testData = (tests & HeaderTest.Extract) != 0;

                baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin);
                if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) {
                    throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset));
                }

                short extractVersion = ( short )ReadLEUshort();
                short localFlags = ( short )ReadLEUshort();
                short compressionMethod = ( short )ReadLEUshort();
                short fileTime = ( short )ReadLEUshort();
                short fileDate = ( short )ReadLEUshort();
                uint crcValue = ReadLEUint();
                long size = ReadLEUint();
                long compressedSize = ReadLEUint();
                int storedNameLength = ReadLEUshort();
                int extraDataLength = ReadLEUshort();

                if ( testData ) {
                    if ( entry.IsFile ) {
                        if ( !entry.IsCompressionMethodSupported() ) {
                            throw new ZipException("Compression method not supported");
                        }

                        if ( (extractVersion > ZipConstants.VersionMadeBy)
                            || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64)) ) {
                            throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion));
                        }

                        if ( (localFlags & ( int )(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0 ) {
                            throw new ZipException("The library does not support the zip version required to extract this entry");
                        }
                    }
                }

                if ( testHeader ) {
                    if ((extractVersion <= 63) &&	// Ignore later versions as we dont know about them..
                        (extractVersion != 10) &&
                        (extractVersion != 11) &&
                        (extractVersion != 20) &&
                        (extractVersion != 21) &&
                        (extractVersion != 25) &&
                        (extractVersion != 27) &&
                        (extractVersion != 45) &&
                        (extractVersion != 46) &&
                        (extractVersion != 50) &&
                        (extractVersion != 51) &&
                        (extractVersion != 52) &&
                        (extractVersion != 61) &&
                        (extractVersion != 62) &&
                        (extractVersion != 63)
                        ) {
                        throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion));
                    }

                    // Local entry flags dont have reserved bit set on.
                    if ( (localFlags & ( int )(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0 ) {
                        throw new ZipException("Reserved bit flags cannot be set.");
                    }

                    // Encryption requires extract version >= 20
                    if ( ((localFlags & ( int )GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20) ) {
                        throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion));
                    }

                    // Strong encryption requires encryption flag to be set and extract version >= 50.
                    if ( (localFlags & (int)GeneralBitFlags.StrongEncryption) != 0 ) {
                        if ( (localFlags & (int)GeneralBitFlags.Encrypted) == 0 ) {
                            throw new ZipException("Strong encryption flag set but encryption flag is not set");
                        }

                        if ( extractVersion < 50 ) {
                            throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion));
                        }
                    }

                    // Patched entries require extract version >= 27
                    if ( ((localFlags & ( int )GeneralBitFlags.Patched) != 0) && (extractVersion < 27) ) {
                        throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion));
                    }

                    // Central header flags match local entry flags.
                    if ( localFlags != entry.Flags ) {
                        throw new ZipException("Central header/local header flags mismatch");
                    }

                    // Central header compression method matches local entry
                    if ( entry.CompressionMethod != ( CompressionMethod )compressionMethod ) {
                        throw new ZipException("Central header/local header compression method mismatch");
                    }

                    // Strong encryption and extract version match
                    if ( (localFlags & ( int )GeneralBitFlags.StrongEncryption) != 0 ) {
                        if ( extractVersion < 62 ) {
                            throw new ZipException("Strong encryption flag set but version not high enough");
                        }
                    }

                    if ( (localFlags & ( int )GeneralBitFlags.HeaderMasked) != 0 ) {
                        if ( (fileTime != 0) || (fileDate != 0) ) {
                            throw new ZipException("Header masked set but date/time values non-zero");
                        }
                    }

                    if ( (localFlags & ( int )GeneralBitFlags.Descriptor) == 0 ) {
                        if ( crcValue != (uint)entry.Crc ) {
                            throw new ZipException("Central header/local header crc mismatch");
                        }
                    }

                    // Crc valid for empty entry.
                    if ( (size == 0) && (compressedSize == 0) ) {
                        if ( crcValue != 0 ) {
                            throw new ZipException("Invalid CRC for empty entry");
                        }
                    }

                    // TODO: make test more correct...  can't compare lengths as was done originally as this can fail for MBCS strings
                    // Assuming a code page at this point is not valid?  Best is to store the name length in the ZipEntry probably
                    if ( entry.Name.Length > storedNameLength ) {
                        throw new ZipException("File name length mismatch");
                    }

                    byte[] nameData = new byte[storedNameLength];
                    StreamUtils.ReadFully(baseStream_, nameData);

                    string localName = ZipConstants.ConvertToStringExt(localFlags, nameData);

                    // Central directory and local entry name match
                    if ( localName != entry.Name ) {
                        throw new ZipException("Central header and local header file name mismatch");
                    }

                    // Directories have zero size.
                    if ( entry.IsDirectory ) {
                        if ( (compressedSize != 0) || (size != 0) ) {
                            throw new ZipException("Directory cannot have size");
                        }
                    }

                    if ( !ZipNameTransform.IsValidName(localName, true) ) {
                        throw new ZipException("Name is invalid");
                    }

                    byte[] data = new byte[extraDataLength];
                    StreamUtils.ReadFully(baseStream_, data);
                    ZipExtraData ed = new ZipExtraData(data);

                    // Extra data / zip64 checks
                    if ( ed.Find(1) ) {
                        // Zip64 extra data but 'extract version' is too low
                        if ( extractVersion < ZipConstants.VersionZip64 ) {
                            throw new ZipException(
                                string.Format("Extra data contains Zip64 information but version {0}.{1} is not high enough",
                                extractVersion / 10, extractVersion % 10));
                        }

                        // Zip64 extra data but size fields dont indicate its required.
                        if ( (( uint )size != uint.MaxValue) && (( uint )compressedSize != uint.MaxValue) ) {
                            throw new ZipException("Entry sizes not correct for Zip64");
                        }

                        size = ed.ReadLong();
                        compressedSize = ed.ReadLong();
                    }
                    else {
                        // No zip64 extra data but entry requires it.
                        if ( (extractVersion >= ZipConstants.VersionZip64) &&
                            ((( uint )size == uint.MaxValue) || (( uint )compressedSize == uint.MaxValue)) ) {
                            throw new ZipException("Required Zip64 extended information missing");
                        }
                    }
                }

                int extraLength = storedNameLength + extraDataLength;
                return offsetOfFirstEntry + entry.Offset + ZipConstants.LocalHeaderBaseSize + extraLength;
            }
        }
Beispiel #24
0
        // 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);
            }
        }
 private static void AddExtraDataAES(ZipEntry entry, ZipExtraData extraData)
 {
     // Vendor Version: AE-1 IS 1. AE-2 is 2. With AE-2 no CRC is required and 0 is stored.
     const int VENDOR_VERSION = 2;
     // Vendor ID is the two ASCII characters "AE".
     const int VENDOR_ID = 0x4541; //not 6965;
     extraData.StartNewEntry();
     // Pack AES extra data field see http://www.winzip.com/aes_info.htm
     //extraData.AddLeShort(7);							// Data size (currently 7)
     extraData.AddLeShort(VENDOR_VERSION); // 2 = AE-2
     extraData.AddLeShort(VENDOR_ID); // "AE"
     extraData.AddData(entry.AESEncryptionStrength); //  1 = 128, 2 = 192, 3 = 256
     extraData.AddLeShort((int) entry.CompressionMethod);
     // The actual compression method used to compress the file
     extraData.AddNewEntry(0x9901);
 }
Beispiel #26
0
        internal void ProcessExtraData(bool localHeader)
        {
            ZipExtraData data = new ZipExtraData(this.extra);

            if (data.Find(1))
            {
                if ((this.versionToExtract & 0xff) < 0x2d)
                {
                    throw new ZipException("Zip64 Extended information found but version is not valid");
                }
                this.forceZip64_ = true;
                if (data.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }
                if (localHeader || (this.size == 0xffffffffL))
                {
                    this.size = (ulong)data.ReadLong();
                }
                if (localHeader || (this.compressedSize == 0xffffffffL))
                {
                    this.compressedSize = (ulong)data.ReadLong();
                }
                if (!localHeader && (this.offset == 0xffffffffL))
                {
                    this.offset = data.ReadLong();
                }
            }
            else if (((this.versionToExtract & 0xff) >= 0x2d) && ((this.size == 0xffffffffL) || (this.compressedSize == 0xffffffffL)))
            {
                throw new ZipException("Zip64 Extended information required but is missing.");
            }
            if (data.Find(10))
            {
                if (data.ValueLength < 8)
                {
                    throw new ZipException("NTFS Extra data invalid");
                }
                data.ReadInt();
                while (data.UnreadCount >= 4)
                {
                    int num    = data.ReadShort();
                    int amount = data.ReadShort();
                    if (num == 1)
                    {
                        if (amount >= 0x18)
                        {
                            long fileTime = data.ReadLong();
                            data.ReadLong();
                            data.ReadLong();
                            this.DateTime = System.DateTime.FromFileTime(fileTime);
                            return;
                        }
                        return;
                    }
                    data.Skip(amount);
                }
            }
            else if (data.Find(0x5455))
            {
                int valueLength = data.ValueLength;
                if (((data.ReadByte() & 1) != 0) && (valueLength >= 5))
                {
                    int             seconds = data.ReadInt();
                    System.DateTime time    = new System.DateTime(0x7b2, 1, 1, 0, 0, 0);
                    this.DateTime = (time.ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime();
                }
            }
        }
        // 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);
            }
        }
Beispiel #28
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);
                }
            }
        }
Beispiel #29
0
        internal void ProcessExtraData(bool localHeader)
        {
            ZipExtraData extraData = new ZipExtraData(this.extra);

            if (!extraData.Find(1))
            {
                if (((this.versionToExtract & 0xff) >= 0x2d) && ((this.size == 0xffffffffUL) || (this.compressedSize == 0xffffffffUL)))
                {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }
            else
            {
                this.forceZip64_ = true;
                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }
                if (localHeader || (this.size == 0xffffffffUL))
                {
                    this.size = (ulong)extraData.ReadLong();
                }
                if (localHeader || (this.compressedSize == 0xffffffffUL))
                {
                    this.compressedSize = (ulong)extraData.ReadLong();
                }
                if (!localHeader && (this.offset == 0xffffffffUL))
                {
                    this.offset = extraData.ReadLong();
                }
            }
            if (!extraData.Find(10))
            {
                if (extraData.Find(0x5455))
                {
                    int valueLength = extraData.ValueLength;
                    if (((extraData.ReadByte() & 1) != 0) && (valueLength >= 5))
                    {
                        int seconds = extraData.ReadInt();
                        this.DateTime = (new System.DateTime(0x7b2, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, seconds, 0)).ToLocalTime();
                    }
                }
            }
            else
            {
                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("NTFS Extra data invalid");
                }
                extraData.ReadInt();
                while (extraData.UnreadCount >= 4)
                {
                    int amount = extraData.ReadShort();
                    if (extraData.ReadShort() == 1)
                    {
                        if (amount >= 0x18)
                        {
                            long fileTime = extraData.ReadLong();
                            extraData.ReadLong();
                            extraData.ReadLong();
                            this.DateTime = System.DateTime.FromFileTime(fileTime);
                        }
                        break;
                    }
                    extraData.Skip(amount);
                }
            }
            if (this.method == ICSharpCode.SharpZipLib.Zip.CompressionMethod.WinZipAES)
            {
                this.ProcessAESExtraData(extraData);
            }
        }
        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);
            }
        }
Beispiel #31
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);
            }
        }
 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;
     }
 }
Beispiel #33
0
        public void ExceedSize()
        {
            ZipExtraData zed = new ZipExtraData();
            byte[] buffer = new byte[65506];
            zed.AddEntry(1, buffer);
            Assert.AreEqual(65510, zed.Length);
            zed.AddEntry(2, new byte[21]);
            Assert.AreEqual(65535, zed.Length);

            bool caught = false;
            try {
                zed.AddEntry(3, null);
            }
            catch {
                caught = true;
            }

            Assert.IsTrue(caught, "Expected an exception when max size exceeded");
            Assert.AreEqual(65535, zed.Length);

            zed.Delete(2);
            Assert.AreEqual(65510, zed.Length);

            caught = false;
            try {
                zed.AddEntry(2, new byte[22]);
            }
            catch {
                caught = true;
            }
            Assert.IsTrue(caught, "Expected an exception when max size exceeded");
            Assert.AreEqual(65510, zed.Length);
        }
        public void PutNextEntry(ZipEntry entry)
        {
            bool hasCrc;

            if (entry == null)
            {
                throw new ArgumentNullException("entry");
            }
            if (this.entries == null)
            {
                throw new InvalidOperationException("ZipOutputStream was finished");
            }
            if (this.curEntry != null)
            {
                this.CloseEntry();
            }
            if (this.entries.Count == 0x7fffffff)
            {
                throw new ZipException("Too many entries for Zip file");
            }
            CompressionMethod compressionMethod = entry.CompressionMethod;
            int defaultCompressionLevel         = this.defaultCompressionLevel;

            entry.Flags          &= 0x800;
            this.patchEntryHeader = false;
            if (entry.Size == 0L)
            {
                entry.CompressedSize = entry.Size;
                entry.Crc            = 0L;
                compressionMethod    = CompressionMethod.Stored;
                hasCrc = true;
            }
            else
            {
                hasCrc = (entry.Size >= 0L) && entry.HasCrc;
                if (compressionMethod == CompressionMethod.Stored)
                {
                    if (!hasCrc)
                    {
                        if (!base.CanPatchEntries)
                        {
                            compressionMethod       = CompressionMethod.Deflated;
                            defaultCompressionLevel = 0;
                        }
                    }
                    else
                    {
                        entry.CompressedSize = entry.Size;
                        hasCrc = entry.HasCrc;
                    }
                }
            }
            if (!hasCrc)
            {
                if (!base.CanPatchEntries)
                {
                    entry.Flags |= 8;
                }
                else
                {
                    this.patchEntryHeader = true;
                }
            }
            if (base.Password != null)
            {
                entry.IsCrypted = true;
                if (entry.Crc < 0L)
                {
                    entry.Flags |= 8;
                }
            }
            entry.Offset            = this.offset;
            entry.CompressionMethod = compressionMethod;
            this.curMethod          = compressionMethod;
            this.sizePatchPos       = -1L;
            if ((this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.On) || ((entry.Size < 0L) && (this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.Dynamic)))
            {
                entry.ForceZip64();
            }
            this.WriteLeInt(0x4034b50);
            this.WriteLeShort(entry.Version);
            this.WriteLeShort(entry.Flags);
            this.WriteLeShort((byte)entry.CompressionMethodForHeader);
            this.WriteLeInt((int)entry.DosTime);
            if (hasCrc)
            {
                this.WriteLeInt((int)entry.Crc);
                if (entry.LocalHeaderRequiresZip64)
                {
                    this.WriteLeInt(-1);
                    this.WriteLeInt(-1);
                }
                else
                {
                    this.WriteLeInt(entry.IsCrypted ? (((int)entry.CompressedSize) + 12) : ((int)entry.CompressedSize));
                    this.WriteLeInt((int)entry.Size);
                }
            }
            else
            {
                if (this.patchEntryHeader)
                {
                    this.crcPatchPos = base.baseOutputStream_.Position;
                }
                this.WriteLeInt(0);
                if (this.patchEntryHeader)
                {
                    this.sizePatchPos = base.baseOutputStream_.Position;
                }
                if (entry.LocalHeaderRequiresZip64 || this.patchEntryHeader)
                {
                    this.WriteLeInt(-1);
                    this.WriteLeInt(-1);
                }
                else
                {
                    this.WriteLeInt(0);
                    this.WriteLeInt(0);
                }
            }
            byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
            if (buffer.Length > 0xffff)
            {
                throw new ZipException("Entry name too long.");
            }
            ZipExtraData extraData = new ZipExtraData(entry.ExtraData);

            if (entry.LocalHeaderRequiresZip64)
            {
                extraData.StartNewEntry();
                if (hasCrc)
                {
                    extraData.AddLeLong(entry.Size);
                    extraData.AddLeLong(entry.CompressedSize);
                }
                else
                {
                    extraData.AddLeLong(-1L);
                    extraData.AddLeLong(-1L);
                }
                extraData.AddNewEntry(1);
                if (!extraData.Find(1))
                {
                    throw new ZipException("Internal error cant find extra data");
                }
                if (this.patchEntryHeader)
                {
                    this.sizePatchPos = extraData.CurrentReadIndex;
                }
            }
            else
            {
                extraData.Delete(1);
            }
            if (entry.AESKeySize > 0)
            {
                AddExtraDataAES(entry, extraData);
            }
            byte[] entryData = extraData.GetEntryData();
            this.WriteLeShort(buffer.Length);
            this.WriteLeShort(entryData.Length);
            if (buffer.Length > 0)
            {
                base.baseOutputStream_.Write(buffer, 0, buffer.Length);
            }
            if (entry.LocalHeaderRequiresZip64 && this.patchEntryHeader)
            {
                this.sizePatchPos += base.baseOutputStream_.Position;
            }
            if (entryData.Length > 0)
            {
                base.baseOutputStream_.Write(entryData, 0, entryData.Length);
            }
            this.offset += (30 + buffer.Length) + entryData.Length;
            if (entry.AESKeySize > 0)
            {
                this.offset += entry.AESOverheadSize;
            }
            this.curEntry = entry;
            this.crc.Reset();
            if (compressionMethod == CompressionMethod.Deflated)
            {
                base.deflater_.Reset();
                base.deflater_.SetLevel(defaultCompressionLevel);
            }
            this.size = 0L;
            if (entry.IsCrypted)
            {
                if (entry.AESKeySize > 0)
                {
                    this.WriteAESHeader(entry);
                }
                else if (entry.Crc < 0L)
                {
                    this.WriteEncryptionHeader(entry.DosTime << 0x10);
                }
                else
                {
                    this.WriteEncryptionHeader(entry.Crc);
                }
            }
        }
Beispiel #35
0
        public void ReadOverrunShort()
        {
            ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 });
            Assert.AreEqual(4, zed.Length, "Length should be 4");
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            // Empty Tag
            bool exceptionCaught = false;
            try {
                zed.ReadShort();
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");

            // Single byte
            zed = new ZipExtraData(new byte[] { 1, 0, 1, 0, 1 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            exceptionCaught = false;
            try {
                zed.ReadShort();
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");

            zed = new ZipExtraData(new byte[] { 1, 0, 2, 0, 1, 2 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            zed.ReadShort();

            exceptionCaught = false;
            try {
                zed.ReadShort();
            }
            catch (ZipException) {
                exceptionCaught = true;
            }
            Assert.IsTrue(exceptionCaught, "Expected EOS exception");
        }
Beispiel #36
0
		public void ReadOverrunLong()
		{
			ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 });
			Assert.AreEqual(4, zed.Length, "Length should be 4");
			Assert.IsTrue(zed.Find(1), "Should find tag 1");

			// Empty Tag
			bool exceptionCaught = false;
			try
			{
				zed.ReadLong();
			}
			catch (ZipException)
			{
				exceptionCaught = true;
			}
			Assert.IsTrue(exceptionCaught, "Expected EOS exception");

			// seven bytes
			zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 });
			Assert.IsTrue(zed.Find(1), "Should find tag 1");

			exceptionCaught = false;
			try
			{
				zed.ReadLong();
			}
			catch (ZipException)
			{
				exceptionCaught = true;
			}
			Assert.IsTrue(exceptionCaught, "Expected EOS exception");

			zed = new ZipExtraData(new byte[] { 1, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9F�5���5���5��5@�5��5��5��5�թ5���5���5�έ5��5���5@թ5��5P��5@Ԣ5 ��5���5 �5��5���5��5P!�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5�h�5�N�5 �5�έ5PN�5@a�50;�5�߮5�M�50O�5�M�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5K�5��5���5��5�!�5F�5���5���5��5p�5��5��5�5�թ5���5`"�5�έ5��5���5PN�5@a�50;�5`�5 �5@թ5��5P��5@Ԣ5P�5��5 �5��5��5��5P!�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5@K�5p:�5���5��5�!�5F�5���5���5��5P=�5�>�5�>�5�?�5�թ5���5�F�5�έ5��5���5PN�5@a�50;�5@<�5<�5@թ5��5P��5@Ԣ50@�5�@�5 �5��5�C�5��5P!�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5pK�5@^�5���5��5 m�5Po�5���5���5��5 a�5pb�5�b�5�c�5�թ5���5�o�5�έ5��5���5PN�5@a�50;�5`�5�_�5@թ5��5P��5@Ԣ5d�5�d�5�f�5�h�5�f�5�j�5�l�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5�h�5�Q�5 �5�έ5PN�5@a�50;�5�߮5�P�5�P�5@Q�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5�K�5p��5@Ԣ5��5���5���5���5���5��5P��5���5Ћ�5���5�թ5���5���5�έ5��5���5PN�5@a�50;�5@��5��5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5 i�5pT�5 �5�έ5PN�5@a�50;�5�߮5PS�5�S�5�S�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5�K�5�5���5��5н�5P��5���5���5��5�5`��5���5���5�թ5���5���5�έ5��5���5@թ5��5P��5@Ԣ5�5���5��5P��5�5���59�5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5L�5�׺5 �5�έ5PN�5@a�50;�5�6�ֺ5 ��5�ֺ5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�50L�50ߺ5���5��5��5�5���5���5��5�5`�5��5��5�թ5���5p�5�έ5��5���5@թ5��5P��5@Ԣ5��5��50�5p�5p�5��5��5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5Pi�5PW�5 �5�έ5PN�5@a�50;�5�߮5�U�50V�5�V�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5`L�5��5���5��5��5�5���5���5��5�	�5�
�5�5 �5�թ5���5��5�έ5��5���5@թ5��5P��5@Ԣ5`�5��50�5p�5��5��5��5Ѐ�5�F�5���5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5@;�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5Ph�5�έ5�w�5�o�5�L�5�-�5���5��5н�5P��5���5���5��5�0�5 2�5P2�5p3�5�թ5���5P9�5�έ5��5���5PN�5@a�50;�5�/�5@/�5@թ5��5P��5@Ԣ5�3�5@4�5��5P��5�6�5���59�5Ѐ�5�F�5���5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5`�5�N�5 �5�έ5PN�5ж�5 N�5�߮5�M�50O�5�M�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5��5�Q�5 �5�έ5PN�5ж�5 N�5�߮5�P�5�P�5@Q�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5��5pT�5 �5�έ5PN�5ж�5 N�5�߮5PS�5�S�5�S�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5��5PW�5 �5�έ5PN�5ж�5 N�5�߮5�U�50V�5�V�5P��5�M�5�X�5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�ʮ5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�i�5�'�5�έ5�w�5�o�5 ��5�׺5 �5�έ5PN�5ж�5 N�5�6�ֺ5 ��5�ֺ5YukonServerContainer_Cryptencrypted_filenametableconfigfile%X%X%X%X%Xe:\sql9_sp2_t\sql\picasso\engine\src\pf\ds\pfssfilesys.cppConfigFile\VersionHighConfigFile\VersionLowConfigFile\IsEncryptedConfigFile\CSPNameConfigFile\CSPTypeConfigFile\EncryptionAlgorithmConfigFile\HashAlgorithmConfigFile\KeyLengthnametable.tmpPFSSDirectory::CreateDirPFSSDirectory::RenameDirPFSSDirectory::DeleteDirPFSSDirectory::OpenFilePFSSDirectory::RenameFilePFSSDirectory::CopyFileWPFSSDirectory::MoveFileWPFSSDirectory::DeleteFileWPFSSDirectory::GetSize�r	6��5���5�}�5�q�5Pr�5�r�5ps�5��5�~�5�s�5�s�5�s�5t�5=�5`t�5�t�5�t�5�}�5�"�5 ��5@߹5�t�5p��5u�5 u�5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5�έ5@Ԣ5�έ5�{�5�o�5���5 ��5�"�5p�5�έ5�6�6���5���5p��5���50�5��5�"�5 ��5���50��50��50��5 �5 �5 �50�5�έ5@Ԣ5��5��5���5�!�5�5��5�{�5�N�5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5�"�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5@�5��5`�5P�5N�5@Ԣ5@Ԣ5�έ5�έ5@Ԣ5`��5�5�5 �5��5��5@�5R�5��5��5@N�5@a�50;�5@�5��5��5��5��5�6�u�5�O�5�O�5`�5��50͈5��5P��5�!�5�5��5�{�5P��5P-�5���5@z�5@z�5@z�5@z�5��5�x�5�~�5���5Ѐ�5��5�x�50w�5�x�50w�5 ��5@߹5P�5�p�5@�5@��5`��5�t�5p��5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5��5`c�5�έ5�{�5�o�5��5��5��5��5���5���5�έ5�6@�5Н�5�M�5`F�5p"�5P"�5"�5p��5�r	6��5���5�}�5�q�5Pr�5�r�5ps�5��5�~�5�s�5�s�5�s�5t�5=�5`t�5�t�5�t�5�}�5"�5 ��5@߹5�t�5p��5u�5 u�5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5�έ5@Ԣ5�έ5�{�5�o�5��5��5�!�5��50�5P��5P-�5���5@z�5@z�5@z�5@z�5��5�x�5�~�5���5Ѐ�5��5�x�50w�5�x�50w�5 ��5@߹5P�5�p�5@�5@��5`��5�t�5p��5p{�5 ��5 {�5p�5�u�5���5�u�5���5���5�u�5v�5@{�5��5`c�5�έ5�{�5�o�5�5��5��5��5���5���5�έ5�6@�5���5н�5�5P�5�5���5 ��5p�5��5P+�5�.�5p�5��5 �5��5��5�5 �5@�5 �5p�5��50�50�5��5@Ԣ5�(�5M�5��5@Ԣ5�5�]6�]6 ^6`^6�^6PFXmlEncodeAndAddStringe:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfxmlconvert.cppPFBufferedMemConnection::Connecte:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfbufferedstream.cpp�N�5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5pN�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5P3�5PN�5�4�5�6 5�5P�5p5�5@Ԣ5@߹5 4�5@N�5@a�50;�5�5�507�5�5���5�O�5 N�5�u�5�O�5�O�5���5�u�5PFCompressedStream::Inite:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfcompressedstream.cppCompressed streamPFCompressedStream::CopyTo�N�5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5pN�5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5�>�50<�5A�5P<�5`A�5p=�5`C�5�=�5�=�5�@�5�?�5@N�5@a�50;�5�C�5pF�5��5@=�5�G�5 N�5�<�5�<�5=�5p<�5PJ�5PFChunkCursor::GetNextBlocke:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pftcp.cppPCXAcceptBuffer::AsyncAcceptlocalhost(local)localPFIXAConnectionTransport::SetPasswordPFIXAConnectionTransport::GetPasswordP��5��5P��5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5`��5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5���5�w�5�o�5���5k�5P��5@�5���5@z�5@z�5@z�5@z�5�x�5�x�5�~�5�p�5�~�5�w�5�x�50w�5�x�50w�5��5@Ԣ5`��5�p�5@�5�z�5Pv�5�z�5Pv�5@y�5���5�w�5�w�5Pv�5Pv�5�w�5�w�5�w�5�w�5�w�5�w�5�έ5@Ԣ5 y�5�w�5�o�5���5P�5p��5PFSOAPMessage::BeginMessagee:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfsoapmsg.cppPFHTTPConnection::Connecte:\sql9_sp2_t\sql\picasso\engine\src\pf\util\pfhttp.cppMSOLAP 9.0 ClientPFHTTPConnection::RunProxyAutodetectionStepPFHTTPConnection::CreateStreamPFHTTPStream::WriteHttpDataContent-Type: 
Beispiel #37
0
        public void UnreadCountValid()
        {
            ZipExtraData zed = new ZipExtraData(new byte[] { 1, 0, 0, 0 });
            Assert.AreEqual(4, zed.Length, "Length should be 4");
            Assert.IsTrue(zed.Find(1), "Should find tag 1");
            Assert.AreEqual(0, zed.UnreadCount);

            // seven bytes
            zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 });
            Assert.IsTrue(zed.Find(1), "Should find tag 1");

            for (int i = 0; i < 7; ++i) {
                Assert.AreEqual(7 - i, zed.UnreadCount);
                zed.ReadByte();
            }

            zed.ReadByte();
            Assert.AreEqual(0, zed.UnreadCount);
        }
Beispiel #38
0
        /// <summary>
        /// Process extra data fields updating the entry based on the contents.
        /// </summary>
        /// <param name="localHeader">True if the extra data fields should be handled
        /// for a local header, rather than for a central header.
        /// </param>
        internal void ProcessExtraData(bool localHeader)
        {
            ZipExtraData extraData = new ZipExtraData(this.extra);

            if (extraData.Find(0x0001))
            {
                if ((versionToExtract & 0xff) < ZipConstants.VersionZip64)
                {
                    throw new ZipException("Zip64 Extended information found but version is not valid");
                }

                // The recorded size will change but remember that this is zip64.
                forceZip64_ = true;

                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }

                if (localHeader || (size == uint.MaxValue))
                {
                    size = (ulong)extraData.ReadLong();
                }

                if (localHeader || (compressedSize == uint.MaxValue))
                {
                    compressedSize = (ulong)extraData.ReadLong();
                }
            }
            else
            {
                if (
                    ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
                    ((size == uint.MaxValue) ||
                     (compressedSize == uint.MaxValue)))
                {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }

            /* TODO: Testing for handling of windows extra data
             * if ( extraData.Find(10) ) {
             *  // No room for any tags.
             *  if ( extraData.ValueLength < 8 ) {
             *   throw new ZipException("NTFS Extra data invalid");
             *  }
             *
             *  extraData.ReadInt(); // Reserved
             *
             *  while ( extraData.UnreadCount >= 4 ) {
             *   int ntfsTag = extraData.ReadShort();
             *   int ntfsLength = extraData.ReadShort();
             *   if ( ntfsTag == 1 ) {
             *    if ( ntfsLength >= 24 ) {
             *     long lastModification = extraData.ReadLong();
             *     long lastAccess = extraData.ReadLong();
             *     long createTime = extraData.ReadLong();
             *
             *     DateTime = System.DateTime.FromFileTime(lastModification);
             *    }
             *    break;
             *   }
             *   else {
             *    // An unknown NTFS tag so simply skip it.
             *    extraData.Skip(ntfsLength);
             *   }
             *  }
             * }
             * else
             */
            if (extraData.Find(0x5455))
            {
                int length = extraData.ValueLength;
                int flags  = extraData.ReadByte();

                // Can include other times but these are ignored.  Length of data should
                // actually be 1 + 4 * no of bits in flags.
                if (((flags & 1) != 0) && (length >= 5))
                {
                    int iTime = extraData.ReadInt();

                    DateTime = (new System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() +
                                new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime();
                }
            }
        }
        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);
            }
        }
        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);
                }
            }
        }
        /// <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);
                    }
                }
            }
        }
        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;
        }
        /// <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;
        }
Beispiel #44
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;
		}
Beispiel #45
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;
     }
 }
        /// <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 (ZipEntryM 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 (entry.AESKeySize > 0)
                {
                    AddExtraDataAES(entry, ed);
                }
                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;
        }
Beispiel #47
0
		/// <summary>
		/// Process extra data fields updating the entry based on the contents.
		/// </summary>
		/// <param name="localHeader">True if the extra data fields should be handled
		/// for a local header, rather than for a central header.
		/// </param>
		internal void ProcessExtraData(bool localHeader)
		{
			ZipExtraData extraData = new ZipExtraData(this.extra);

			if ( extraData.Find(0x0001) ) {
                // Version required to extract is ignored here as some archivers dont set it correctly
                // in theory it should be version 45 or higher

				// The recorded size will change but remember that this is zip64.
				forceZip64_ = true;

				if ( extraData.ValueLength < 4 ) {
					throw new ZipException("Extra data extended Zip64 information length is invalid");
				}

				if ( localHeader || (size == uint.MaxValue) ) {
					size = (ulong)extraData.ReadLong();
				}

				if ( localHeader || (compressedSize == uint.MaxValue) ) {
					compressedSize = (ulong)extraData.ReadLong();
				}

				if ( !localHeader && (offset == uint.MaxValue) ) {
					offset = extraData.ReadLong();
				}

                // Disk number on which file starts is ignored
			}
			else {
				if ( 
					((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
					((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
				) {
					throw new ZipException("Zip64 Extended information required but is missing.");
				}
			}

			dateTime = GetDateTime(extraData);
			if (method == CompressionMethod.WinZipAES) {
				ProcessAESExtraData(extraData);
			}
		}
Beispiel #48
0
        private DateTime GetDateTime(ZipExtraData extraData)
        {
            // Check for NT timestamp
            // NOTE: Disable by default to match behavior of InfoZIP
            #if RESPECT_NT_TIMESTAMP
            NTTaggedData ntData = extraData.GetData<NTTaggedData>();
            if (ntData != null)
                return ntData.LastModificationTime;
            #endif

            // Check for Unix timestamp
            ExtendedUnixData unixData = extraData.GetData<ExtendedUnixData>();
            if (unixData != null &&
                // Only apply modification time, but require all other values to be present
                // This is done to match InfoZIP's behaviour
                ((unixData.Include & ExtendedUnixData.Flags.ModificationTime) != 0) &&
                ((unixData.Include & ExtendedUnixData.Flags.AccessTime) != 0) &&
                ((unixData.Include & ExtendedUnixData.Flags.CreateTime) != 0))
                return unixData.ModificationTime;

            // Fall back to DOS time
            uint sec = Math.Min(59, 2 * (dosTime & 0x1f));
            uint min = Math.Min(59, (dosTime >> 5) & 0x3f);
            uint hrs = Math.Min(23, (dosTime >> 11) & 0x1f);
            uint mon = Math.Max(1, Math.Min(12, ((dosTime >> 21) & 0xf)));
            uint year = ((dosTime >> 25) & 0x7f) + 1980;
            int day = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)mon), (int)((dosTime >> 16) & 0x1f)));
            return new DateTime((int)year, (int)mon, day, (int)hrs, (int)min, (int)sec, DateTimeKind.Utc);
        }
Beispiel #49
0
        /// <summary>
        /// Process extra data fields updating the entry based on the contents.
        /// </summary>
        /// <param name="localHeader">True if the extra data fields should be handled
        /// for a local header, rather than for a central header.
        /// </param>
        internal void ProcessExtraData(bool localHeader)
        {
            var extraData = new ZipExtraData(this.extra);

            if (extraData.Find(0x0001))
            {
                // Version required to extract is ignored here as some archivers dont set it correctly
                // in theory it should be version 45 or higher

                // The recorded size will change but remember that this is zip64.
                forceZip64_ = true;

                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }

                // (localHeader ||) was deleted, because actually there is no specific difference with reading sizes between local header & central directory
                // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
                // ...
                // 4.4  Explanation of fields
                // ...
                //	4.4.8 compressed size: (4 bytes)
                //	4.4.9 uncompressed size: (4 bytes)
                //
                //		The size of the file compressed (4.4.8) and uncompressed,
                //		(4.4.9) respectively.  When a decryption header is present it
                //		will be placed in front of the file data and the value of the
                //		compressed file size will include the bytes of the decryption
                //		header.  If bit 3 of the general purpose bit flag is set,
                //		these fields are set to zero in the local header and the
                //		correct values are put in the data descriptor and
                //		in the central directory.  If an archive is in ZIP64 format
                //		and the value in this field is 0xFFFFFFFF, the size will be
                //		in the corresponding 8 byte ZIP64 extended information
                //		extra field.  When encrypting the central directory, if the
                //		local header is not in ZIP64 format and general purpose bit
                //		flag 13 is set indicating masking, the value stored for the
                //		uncompressed size in the Local Header will be zero.
                //
                // Othewise there is problem with minizip implementation
                if (size == uint.MaxValue)
                {
                    size = (ulong)extraData.ReadLong();
                }

                if (compressedSize == uint.MaxValue)
                {
                    compressedSize = (ulong)extraData.ReadLong();
                }

                if (!localHeader && (offset == uint.MaxValue))
                {
                    offset = extraData.ReadLong();
                }

                // Disk number on which file starts is ignored
            }
            else
            {
                if (
                    ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
                    ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
                    )
                {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }

            DateTime = GetDateTime(extraData);
            if (method == CompressionMethod.WinZipAES)
            {
                ProcessAESExtraData(extraData);
            }
        }
Beispiel #50
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);
                }
            }
        }
Beispiel #51
0
        /// <summary>
        /// Process extra data fields updating the entry based on the contents.
        /// </summary>
        /// <param name="localHeader">True if the extra data fields should be handled
        /// for a local header, rather than for a central header.
        /// </param>
        internal void ProcessExtraData(bool localHeader)
        {
            var extraData = new ZipExtraData(extra);

            if (extraData.Find(0x0001))
            {
                // Version required to extract is ignored here as some archivers dont set it correctly
                // in theory it should be version 45 or higher

                // The recorded size will change but remember that this is zip64.
                forceZip64_ = true;

                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }

                if (localHeader || (size == uint.MaxValue))
                {
                    size = (ulong) extraData.ReadLong();
                }

                if (localHeader || (compressedSize == uint.MaxValue))
                {
                    compressedSize = (ulong) extraData.ReadLong();
                }

                if (!localHeader && (offset == uint.MaxValue))
                {
                    offset = extraData.ReadLong();
                }

                // Disk number on which file starts is ignored
            }
            else
            {
                if (
                    ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
                    ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
                    )
                {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }

            if (extraData.Find(10))
            {
                // No room for any tags.
                if (extraData.ValueLength < 4)
                {
                    throw new ZipException("NTFS Extra data invalid");
                }

                extraData.ReadInt(); // Reserved

                while (extraData.UnreadCount >= 4)
                {
                    int ntfsTag = extraData.ReadShort();
                    int ntfsLength = extraData.ReadShort();
                    if (ntfsTag == 1)
                    {
                        if (ntfsLength >= 24)
                        {
                            long lastModification = extraData.ReadLong();
                            long lastAccess = extraData.ReadLong();
                            long createTime = extraData.ReadLong();

                            DateTime = DateTime.FromFileTime(lastModification);
                        }
                        break;
                    }
                    else
                    {
                        // An unknown NTFS tag so simply skip it.
                        extraData.Skip(ntfsLength);
                    }
                }
            }
            else if (extraData.Find(0x5455))
            {
                int length = extraData.ValueLength;
                int flags = extraData.ReadByte();

                // Can include other times but these are ignored.  Length of data should
                // actually be 1 + 4 * no of bits in flags.
                if (((flags & 1) != 0) && (length >= 5))
                {
                    int iTime = extraData.ReadInt();

                    DateTime = (new DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() +
                                new TimeSpan(0, 0, 0, iTime, 0)).ToLocalTime();
                }
            }
            if (method == CompressionMethod.WinZipAES)
            {
                ProcessAESExtraData(extraData);
            }
        }
Beispiel #52
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");
        }
Beispiel #53
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);
			}
		}
Beispiel #54
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;
        }
        /// <summary>
        /// Starts a new Zip entry. It automatically closes the previous
        /// entry if present.
        /// All entry elements bar name are optional, but must be correct if present.
        /// If the compression method is stored and the output is not patchable
        /// the compression for that entry is automatically changed to deflate level 0
        /// </summary>
        /// <param name="entry">
        /// the entry.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// if entry passed is null.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// if an I/O error occured.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// if stream was finished
        /// </exception>
        /// <exception cref="ZipException">
        /// Too many entries in the Zip file<br/>
        /// Entry name is too long<br/>
        /// Finish has already been called<br/>
        /// </exception>
        public void PutNextEntry(ZipEntryM entry)
        {
            if (entry == null)
            {
                //throw new ArgumentNullException(//nameof//(entry));
            }

            if (entries == null)
            {
                //throw new InvalidOperationException("ZipOutputStream was finished");
            }

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

            if (entries.Count == int.MaxValue)
            {
                //throw new ZipException("Too many entries for Zip file");
            }

            CompressionMethod method = entry.CompressionMethod;
            int compressionLevel     = defaultCompressionLevel;

            // Clear flags that the library manages internally
            entry.Flags     &= (int)GeneralBitFlags.UnicodeText;
            patchEntryHeader = false;

            bool headerInfoAvailable;

            // No need to compress - definitely no data.
            if (entry.Size == 0)
            {
                entry.CompressedSize = entry.Size;
                entry.Crc            = 0;
                method = CompressionMethod.Stored;
                headerInfoAvailable = true;
            }
            else
            {
                headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc && entry.CompressedSize >= 0;

                // Switch to deflation if storing isnt possible.
                if (method == CompressionMethod.Stored)
                {
                    if (!headerInfoAvailable)
                    {
                        if (!CanPatchEntries)
                        {
                            // Can't patch entries so storing is not possible.
                            method           = CompressionMethod.Deflated;
                            compressionLevel = 0;
                        }
                    }
                    else                       // entry.size must be > 0
                    {
                        entry.CompressedSize = entry.Size;
                        headerInfoAvailable  = entry.HasCrc;
                    }
                }
            }

            if (headerInfoAvailable == false)
            {
                if (CanPatchEntries == false)
                {
                    // Only way to record size and compressed size is to append a data descriptor
                    // after compressed data.

                    // Stored entries of this form have already been converted to deflating.
                    entry.Flags |= 8;
                }
                else
                {
                    patchEntryHeader = true;
                }
            }

            if (Password != null)
            {
                entry.IsCrypted = true;
                if (entry.Crc < 0)
                {
                    // Need to append a data descriptor as the crc isnt available for use
                    // with encryption, the date is used instead.  Setting the flag
                    // indicates this to the decompressor.
                    entry.Flags |= 8;
                }
            }

            entry.Offset            = offset;
            entry.CompressionMethod = (CompressionMethod)method;

            curMethod    = method;
            sizePatchPos = -1;

            if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic)))
            {
                entry.ForceZip64();
            }

            // Write the local file header
            WriteLeInt(ZipConstants.LocalHeaderSignature);

            WriteLeShort(entry.Version);
            WriteLeShort(entry.Flags);
            WriteLeShort((byte)entry.CompressionMethodForHeader);
            WriteLeInt((int)entry.DosTime);

            // TODO: Refactor header writing.  Its done in several places.
            if (headerInfoAvailable)
            {
                WriteLeInt((int)entry.Crc);
                if (entry.LocalHeaderRequiresZip64)
                {
                    WriteLeInt(-1);
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize);
                    WriteLeInt((int)entry.Size);
                }
            }
            else
            {
                if (patchEntryHeader)
                {
                    crcPatchPos = baseOutputStream_.Position;
                }
                WriteLeInt(0);                  // Crc

                if (patchEntryHeader)
                {
                    sizePatchPos = baseOutputStream_.Position;
                }

                // For local header both sizes appear in Zip64 Extended Information
                if (entry.LocalHeaderRequiresZip64 || patchEntryHeader)
                {
                    WriteLeInt(-1);
                    WriteLeInt(-1);
                }
                else
                {
                    WriteLeInt(0);                      // Compressed size
                    WriteLeInt(0);                      // Uncompressed size
                }
            }

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

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

            var ed = new ZipExtraData(entry.ExtraData);

            if (entry.LocalHeaderRequiresZip64)
            {
                ed.StartNewEntry();
                if (headerInfoAvailable)
                {
                    ed.AddLeLong(entry.Size);
                    ed.AddLeLong(entry.CompressedSize);
                }
                else
                {
                    ed.AddLeLong(-1);
                    ed.AddLeLong(-1);
                }
                ed.AddNewEntry(1);

                if (!ed.Find(1))
                {
                    //throw new ZipException("Internal error cant find extra data");
                }

                if (patchEntryHeader)
                {
                    sizePatchPos = ed.CurrentReadIndex;
                }
            }
            else
            {
                ed.Delete(1);
            }

            if (entry.AESKeySize > 0)
            {
                AddExtraDataAES(entry, ed);
            }
            byte[] extra = ed.GetEntryData();

            WriteLeShort(name.Length);
            WriteLeShort(extra.Length);

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

            if (entry.LocalHeaderRequiresZip64 && patchEntryHeader)
            {
                sizePatchPos += baseOutputStream_.Position;
            }

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

            offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length;
            // Fix offsetOfCentraldir for AES
            if (entry.AESKeySize > 0)
            {
                offset += entry.AESOverheadSize;
            }

            // Activate the entry.
            curEntry = entry;
            crc.Reset();
            if (method == CompressionMethod.Deflated)
            {
                deflater_.Reset();
                deflater_.SetLevel(compressionLevel);
            }
            size = 0;

            if (entry.IsCrypted)
            {
                if (entry.AESKeySize > 0)
                {
                    WriteAESHeader(entry);
                }
                else
                {
                    if (entry.Crc < 0)                                  // so testing Zip will says its ok
                    {
                        WriteEncryptionHeader(entry.DosTime << 16);
                    }
                    else
                    {
                        WriteEncryptionHeader(entry.Crc);
                    }
                }
            }
        }
Beispiel #56
0
        internal void ProcessExtraData(bool localHeader)
        {
            //IL_0171: Unknown result type (might be due to invalid IL or missing references)
            ZipExtraData zipExtraData = new ZipExtraData(extra);

            if (zipExtraData.Find(1))
            {
                forceZip64_ = true;
                if (zipExtraData.ValueLength < 4)
                {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }
                if (localHeader || size == 4294967295u)
                {
                    size = (ulong)zipExtraData.ReadLong();
                }
                if (localHeader || compressedSize == 4294967295u)
                {
                    compressedSize = (ulong)zipExtraData.ReadLong();
                }
                if (!localHeader && offset == 4294967295u)
                {
                    offset = zipExtraData.ReadLong();
                }
            }
            else if ((versionToExtract & 0xFF) >= 45 && (size == 4294967295u || compressedSize == 4294967295u))
            {
                throw new ZipException("Zip64 Extended information required but is missing.");
            }
            if (zipExtraData.Find(10))
            {
                if (zipExtraData.ValueLength < 4)
                {
                    throw new ZipException("NTFS Extra data invalid");
                }
                zipExtraData.ReadInt();
                while (zipExtraData.UnreadCount >= 4)
                {
                    int num  = zipExtraData.ReadShort();
                    int num2 = zipExtraData.ReadShort();
                    if (num == 1)
                    {
                        if (num2 >= 24)
                        {
                            long num3 = zipExtraData.ReadLong();
                            zipExtraData.ReadLong();
                            zipExtraData.ReadLong();
                            DateTime = global::System.DateTime.FromFileTime(num3);
                        }
                        break;
                    }
                    zipExtraData.Skip(num2);
                }
            }
            else if (zipExtraData.Find(21589))
            {
                int valueLength = zipExtraData.ValueLength;
                int num4        = zipExtraData.ReadByte();
                if (((uint)num4 & (true ? 1u : 0u)) != 0 && valueLength >= 5)
                {
                    int num5 = zipExtraData.ReadInt();
                    DateTime = (new global::System.DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime() + new TimeSpan(0, 0, 0, num5, 0)).ToLocalTime();
                }
            }
            if (method == CompressionMethod.WinZipAES)
            {
                ProcessAESExtraData(zipExtraData);
            }
        }
Beispiel #57
0
        /// <summary>
        /// Process extra data fields updating the entry based on the contents.
        /// </summary>
        /// <param name="localHeader">True if the extra data fields should be handled
        /// for a local header, rather than for a central header.
        /// </param>
        internal void ProcessExtraData(bool localHeader)
        {
            var extraData = new ZipExtraData(this.extra);

            if (extraData.Find(0x0001)) {
                // Version required to extract is ignored here as some archivers dont set it correctly
                // in theory it should be version 45 or higher

                // The recorded size will change but remember that this is zip64.
                forceZip64_ = true;

                if (extraData.ValueLength < 4) {
                    throw new ZipException("Extra data extended Zip64 information length is invalid");
                }

                // (localHeader ||) was deleted, because actually there is no specific difference with reading sizes between local header & central directory
                // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
                // ...
                // 4.4  Explanation of fields
                // ...
                //	4.4.8 compressed size: (4 bytes)
                //	4.4.9 uncompressed size: (4 bytes)
                //
                //		The size of the file compressed (4.4.8) and uncompressed,
                //		(4.4.9) respectively.  When a decryption header is present it
                //		will be placed in front of the file data and the value of the
                //		compressed file size will include the bytes of the decryption
                //		header.  If bit 3 of the general purpose bit flag is set,
                //		these fields are set to zero in the local header and the
                //		correct values are put in the data descriptor and
                //		in the central directory.  If an archive is in ZIP64 format
                //		and the value in this field is 0xFFFFFFFF, the size will be
                //		in the corresponding 8 byte ZIP64 extended information
                //		extra field.  When encrypting the central directory, if the
                //		local header is not in ZIP64 format and general purpose bit
                //		flag 13 is set indicating masking, the value stored for the
                //		uncompressed size in the Local Header will be zero.
                //
                // Othewise there is problem with minizip implementation
                if (size == uint.MaxValue) {
                    size = (ulong)extraData.ReadLong();
                }

                if (compressedSize == uint.MaxValue) {
                    compressedSize = (ulong)extraData.ReadLong();
                }

                if (!localHeader && (offset == uint.MaxValue)) {
                    offset = extraData.ReadLong();
                }

                // Disk number on which file starts is ignored
            } else {
                if (
                    ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
                    ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
                ) {
                    throw new ZipException("Zip64 Extended information required but is missing.");
                }
            }

            DateTime = GetDateTime(extraData);
            if (method == CompressionMethod.WinZipAES) {
                ProcessAESExtraData(extraData);
            }
        }
Beispiel #58
0
 private void ProcessAESExtraData(ZipExtraData extraData)
 {
     throw new ZipException("AES unsupported");
 }
Beispiel #59
0
 // For AES the method in the entry is 99, and the real compression method is in the extradata
 //
 private void ProcessAESExtraData(ZipExtraData extraData)
 {
     if (extraData.Find(0x9901)) {
         // Set version and flag for Zipfile.CreateAndInitDecryptionStream
         versionToExtract = ZipConstants.VERSION_AES;            // Ver 5.1 = AES see "Version" getter
                                                                 // Set StrongEncryption flag for ZipFile.CreateAndInitDecryptionStream
         Flags = Flags | (int)GeneralBitFlags.StrongEncryption;
         //
         // Unpack AES extra data field see http://www.winzip.com/aes_info.htm
         int length = extraData.ValueLength;         // Data size currently 7
         if (length < 7)
             throw new ZipException("AES Extra Data Length " + length + " invalid.");
         int ver = extraData.ReadShort();            // Version number (1=AE-1 2=AE-2)
         int vendorId = extraData.ReadShort();       // 2-character vendor ID 0x4541 = "AE"
         int encrStrength = extraData.ReadByte();    // encryption strength 1 = 128 2 = 192 3 = 256
         int actualCompress = extraData.ReadShort(); // The actual compression method used to compress the file
         _aesVer = ver;
         _aesEncryptionStrength = encrStrength;
         method = (CompressionMethod)actualCompress;
     } else
         throw new ZipException("AES Extra Data missing");
 }
Beispiel #60
0
		/// <summary>
		/// Process extra data fields updating the entry based on the contents.
		/// </summary>
		/// <param name="localHeader">True if the extra data fields should be handled
		/// for a local header, rather than for a central header.
		/// </param>
		internal void ProcessExtraData(bool localHeader)
		{
			ZipExtraData extraData = new ZipExtraData(this.extra);

			if ( extraData.Find(0x0001) ) {
				if ( (versionToExtract & 0xff) < ZipConstants.VersionZip64 ) {
					throw new ZipException("Zip64 Extended information found but version is not valid");
				}

				// The recorded size will change but remember that this is zip64.
				forceZip64_ = true;

				if ( extraData.ValueLength < 4 ) {
					throw new ZipException("Extra data extended Zip64 information length is invalid");
				}

				if ( localHeader || (size == uint.MaxValue) ) {
					size = (ulong)extraData.ReadLong();
				}

				if ( localHeader || (compressedSize == uint.MaxValue) ) {
					compressedSize = (ulong)extraData.ReadLong();
				}
			}
			else {
				if ( 
					((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
					( (size == uint.MaxValue) ||
					(compressedSize == uint.MaxValue) )) {
					throw new ZipException("Zip64 Extended information required but is missing.");
				}
			}

/* TODO: Testing for handling of windows extra data
			if ( extraData.Find(10) ) {
				// No room for any tags.
				if ( extraData.ValueLength < 8 ) {
					throw new ZipException("NTFS Extra data invalid");
				}

				extraData.ReadInt(); // Reserved

				while ( extraData.UnreadCount >= 4 ) {
					int ntfsTag = extraData.ReadShort();
					int ntfsLength = extraData.ReadShort();
					if ( ntfsTag == 1 ) {
						if ( ntfsLength >= 24 ) {
							long lastModification = extraData.ReadLong();
							long lastAccess = extraData.ReadLong();
							long createTime = extraData.ReadLong();

							DateTime = System.DateTime.FromFileTime(lastModification);
						}
						break;
					}
					else {
						// An unknown NTFS tag so simply skip it.
						extraData.Skip(ntfsLength);
					}
				}
			}
			else 
*/			
			if ( extraData.Find(0x5455) ) {
				int length = extraData.ValueLength;	
				int flags = extraData.ReadByte();
					
				// Can include other times but these are ignored.  Length of data should
				// actually be 1 + 4 * no of bits in flags.
				if ( ((flags & 1) != 0) && (length >= 5) ) {
					int iTime = extraData.ReadInt();

					DateTime = (new System.DateTime ( 1970, 1, 1, 0, 0, 0 ).ToUniversalTime() +
						new TimeSpan ( 0, 0, 0, iTime, 0 )).ToLocalTime();
				}
			}
		}