Example #1
0
        private static void HandleUnexpectedDataDescriptor(ZipEntry entry)
        {
            // no seek - stream integrity should be protected by the caller

            Stream s = entry.ArchiveStream;

            if (ZipSharedUtilities.ReadInt(s) == entry._Crc32)
            {
                if (ZipSharedUtilities.ReadInt(s) == entry._CompressedSize)
                {
                    if (ZipSharedUtilities.ReadInt(s) != entry._UncompressedSize)
                    {
                        s.Seek(-12L, SeekOrigin.Current);
                    }
                }
                else
                {
                    s.Seek(-8L, SeekOrigin.Current);
                }
            }
            else
            {
                s.Seek(-4L, SeekOrigin.Current);
            }
        }
Example #2
0
        private void InsureUniqueEntry(ZipEntry ze1)
        {
            var normalizedName = ZipSharedUtilities.TrimVolumeAndSwapSlashes(ze1.FileName);

            if (_entriesIndex.ContainsKey(normalizedName))
            {
                throw new ArgumentException(String.Format("The entry '{0}' already exists in the zip archive.", ze1.FileName));
            }
        }
Example #3
0
        private static void ReadCentralDirectoryFooter(ZipFile zf)
        {
            // no seek - stream integrity should be protected by the caller

            Stream s         = zf.ReadStream;
            int    signature = ZipSharedUtilities.ReadSignature(s);

            if (signature != 0x6054b50L)
            {
                s.Seek(-4L, SeekOrigin.Current);
                throw new BadReadException(String.Format("  ZipFile::Read(): Bad signature ({0:X8}) at position 0x{1:X8}", signature, s.Position));
            }
            byte[] block = new byte[0x10];
            zf.ReadStream.Read(block, 0, block.Length);
            ReadZipFileComment(zf);
        }
Example #4
0
        internal static String NameInArchive(String filename, String directoryPathInArchive)
        {
            String result = null;

            if (directoryPathInArchive == null)
            {
                result = filename;
            }
            else if (String.IsNullOrEmpty(directoryPathInArchive))
            {
                result = Path.GetFileName(filename);
            }
            else
            {
                result = Path.Combine(directoryPathInArchive, Path.GetFileName(filename));
            }
            return(ZipSharedUtilities.TrimVolumeAndSwapSlashes(result));
        }
Example #5
0
        private static void ReadZipFileComment(ZipFile zf)
        {
            // no seek - stream integrity should be protected by the caller

            byte[] block = new byte[2];
            zf.ReadStream.Read(block, 0, block.Length);
            short commentLength = (short)(block[0] + (block[1] * 0x100));

            if (commentLength > 0)
            {
                block = new byte[commentLength];
                zf.ReadStream.Read(block, 0, block.Length);
                if (ZipSharedUtilities.HighBytes(block) && (zf._encoding == Encoding.GetEncoding("ibm437")))
                {
                    zf._encoding = Encoding.UTF8;
                }
                zf.Comment = ZipSharedUtilities.StringFromBuffer(block, block.Length, zf._encoding);
            }
        }
Example #6
0
        private void WriteHeader(Stream s, int cycle)
        {
            byte[] bytes = new byte[0x2200];
            int    i     = 0;

            bytes[i++] = 80;
            bytes[i++] = 0x4b;
            bytes[i++] = 3;
            bytes[i++] = 4;
            short VersionNeededToExctract = 20;

            bytes[i++] = (byte)(VersionNeededToExctract & 0xff);
            bytes[i++] = (byte)((VersionNeededToExctract & 0xff00) >> 8);
            byte[] FileNameBytes  = this.GetFileNameBytes();
            short  filenameLength = (short)FileNameBytes.Length;

            this._CommentBytes = null;
            if (!String.IsNullOrEmpty(this._Comment))
            {
                this._CommentBytes = this._Comment.ToByteArray(this._encoding);
            }
            bool setUtf8Bit = this.UseUtf8Encoding && (ZipSharedUtilities.HighBytes(this._CommentBytes) || ZipSharedUtilities.HighBytes(FileNameBytes));

            this._BitField = ((short)0);
            if (setUtf8Bit)
            {
                this._BitField = (short)(this._BitField | 0x800);
            }
            if (!s.CanSeek)
            {
                this._BitField = (short)(this._BitField | 8);
            }
            bytes[i++] = (byte)(this._BitField & 0xff);
            bytes[i++] = (byte)((this._BitField & 0xff00) >> 8);
            if (this.__FileDataPosition == 0L)
            {
                this._UncompressedSize = 0;
                this._CompressedSize   = 0;
                this._Crc32            = 0;
            }
            this.FigureCompressionMethodForWriting(cycle);
            bytes[i++]     = (byte)(this.CompressionMethod & 0xff);
            bytes[i++]     = (byte)((this.CompressionMethod & 0xff00) >> 8);
            this._TimeBlob = ZipSharedUtilities.DateTimeToPacked(this.LastModified);
            bytes[i++]     = (byte)(this._TimeBlob & 0xff);
            bytes[i++]     = (byte)((this._TimeBlob & 0xff00) >> 8);
            bytes[i++]     = (byte)((this._TimeBlob & 0xff0000) >> 0x10);
            bytes[i++]     = (byte)((this._TimeBlob & 0xff000000L) >> 0x18);
            bytes[i++]     = (byte)(this._Crc32 & 0xff);
            bytes[i++]     = (byte)((this._Crc32 & 0xff00) >> 8);
            bytes[i++]     = (byte)((this._Crc32 & 0xff0000) >> 0x10);
            bytes[i++]     = (byte)((this._Crc32 & 0xff000000L) >> 0x18);
            bytes[i++]     = (byte)(this._CompressedSize & 0xff);
            bytes[i++]     = (byte)((this._CompressedSize & 0xff00) >> 8);
            bytes[i++]     = (byte)((this._CompressedSize & 0xff0000) >> 0x10);
            bytes[i++]     = (byte)((this._CompressedSize & 0xff000000L) >> 0x18);
            bytes[i++]     = (byte)(this._UncompressedSize & 0xff);
            bytes[i++]     = (byte)((this._UncompressedSize & 0xff00) >> 8);
            bytes[i++]     = (byte)((this._UncompressedSize & 0xff0000) >> 0x10);
            bytes[i++]     = (byte)((this._UncompressedSize & 0xff000000L) >> 0x18);
            bytes[i++]     = (byte)(filenameLength & 0xff);
            bytes[i++]     = (byte)((filenameLength & 0xff00) >> 8);
            byte[] extra            = null;
            short  ExtraFieldLength = (extra == null) ? ((short)0) : ((short)extra.Length);

            bytes[i++] = (byte)(ExtraFieldLength & 0xff);
            bytes[i++] = (byte)((ExtraFieldLength & 0xff00) >> 8);
            int j = 0;

            j = 0;
            while ((j < FileNameBytes.Length) && ((i + j) < bytes.Length))
            {
                bytes[i + j] = FileNameBytes[j];
                j++;
            }
            i += j;
            if (extra != null)
            {
                j = 0;
                while (j < extra.Length)
                {
                    bytes[i + j] = extra[j];
                    j++;
                }
                i += j;
            }
            CountingStream counter = s as CountingStream;

            this._RelativeOffsetOfHeader = (counter != null) ? counter.BytesWritten : ((int)s.Position);
            this._LengthOfHeader         = i;
            s.Write(bytes, 0, i);
            this._EntryHeader = new byte[i];
            for (j = 0; j < i; j++)
            {
                this._EntryHeader[j] = bytes[j];
            }
        }
Example #7
0
        private static bool ReadHeader(ZipEntry ze, Encoding defaultEncoding)
        {
            // no seek - stream integrity should be protected by the caller

            int bytesRead = 0;

            ze._RelativeOffsetOfHeader = (int)ze.ArchiveStream.Position;
            int signature = ZipSharedUtilities.ReadSignature(ze.ArchiveStream);

            bytesRead += 4;
            if (IsNotValidSig(signature))
            {
                ze.ArchiveStream.Seek(-4L, SeekOrigin.Current);
                if (ZipDirEntry.IsNotValidSig(signature) && (signature != 0x6054b50L))
                {
                    throw new BadReadException(String.Format("  ZipEntry::ReadHeader(): Bad signature (0x{0:X8}) at position  0x{1:X8}", signature, ze.ArchiveStream.Position));
                }
                return(false);
            }
            byte[] block = new byte[0x1a];
            int    n     = ze.ArchiveStream.Read(block, 0, block.Length);

            if (n != block.Length)
            {
                return(false);
            }
            bytesRead += n;
            int i = 0;

            ze._VersionNeeded     = (short)(block[i++] + (block[i++] * 0x100));
            ze._BitField          = (short)(block[i++] + (block[i++] * 0x100));
            ze._CompressionMethod = (short)(block[i++] + (block[i++] * 0x100));
            ze._TimeBlob          = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            ze._LastModified      = ZipSharedUtilities.PackedToDateTime(ze._TimeBlob);
            if ((ze._BitField & 8) != 8)
            {
                ze._Crc32            = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
                ze._CompressedSize   = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
                ze._UncompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            }
            else
            {
                i += 12;
            }
            short filenameLength   = (short)(block[i++] + (block[i++] * 0x100));
            short extraFieldLength = (short)(block[i++] + (block[i++] * 0x100));

            block      = new byte[filenameLength];
            n          = ze.ArchiveStream.Read(block, 0, block.Length);
            bytesRead += n;

            var s1 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.GetEncoding(1251));
            var s2 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.ASCII);
            var s3 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.UTF8);
            var s4 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.Default);
            var s5 = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.GetEncoding(1252));

            if ((ze._BitField & 0x800) == 0x800)
            {
                ze._FileNameInArchive = ZipSharedUtilities.StringFromBuffer(block, block.Length, Encoding.UTF8);
                ze.UseUtf8Encoding    = true;
            }
            else
            {
                ze._FileNameInArchive = ZipSharedUtilities.StringFromBuffer(block, block.Length, defaultEncoding);
                ze._encoding          = defaultEncoding;
            }
            ze._LocalFileName = ze._FileNameInArchive;
            if (extraFieldLength > 0)
            {
                ze._Extra  = new byte[extraFieldLength];
                n          = ze.ArchiveStream.Read(ze._Extra, 0, ze._Extra.Length);
                bytesRead += n;
            }
            if (!ze.FileName.EndsWith("/") && ((ze._BitField & 8) == 8))
            {
                long posn           = ze.ArchiveStream.Position;
                bool wantMore       = true;
                long SizeOfDataRead = 0L;
                int  tries          = 0;
                while (wantMore)
                {
                    tries++;
                    long d = ZipSharedUtilities.FindSignature(ze.ArchiveStream, 0x8074b50);
                    if (d == -1L)
                    {
                        return(false);
                    }
                    SizeOfDataRead += d;
                    block           = new byte[12];
                    n = ze.ArchiveStream.Read(block, 0, block.Length);
                    if (n != 12)
                    {
                        return(false);
                    }
                    bytesRead           += n;
                    i                    = 0;
                    ze._Crc32            = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
                    ze._CompressedSize   = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
                    ze._UncompressedSize = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
                    if (SizeOfDataRead != ze._CompressedSize)
                    {
                        ze.ArchiveStream.Seek(-12L, SeekOrigin.Current);
                        SizeOfDataRead += 4L;
                    }
                }
                ze.ArchiveStream.Seek(posn, SeekOrigin.Begin);
            }
            ze._CompressedFileDataSize = ze._CompressedSize;
            if ((ze._BitField & 1) == 1)
            {
                throw new NotSupportedException("Encryption is not supported");
            }
            ze._TotalEntrySize = bytesRead + ze._CompressedFileDataSize;
            ze._LengthOfHeader = bytesRead;
            return(true);
        }
Example #8
0
        internal static ZipEntry Create(String filename, String nameInArchive, Stream stream)
        {
            if (String.IsNullOrEmpty(filename))
            {
                throw new ZipException("The entry name must be non-null and non-empty.");
            }
            ZipEntry entry = new ZipEntry();

            if (stream != null)
            {
                entry._sourceStream = stream;
                entry._LastModified = DateTime.Now;
            }
            else
            {
                entry._LastModified = (File.Exists(filename) || Directory.Exists(filename)) ? ZipSharedUtilities.RoundToEvenSecond(File.GetLastWriteTime(filename)) : DateTime.Now;
                if (!(entry._LastModified.IsDaylightSavingTime() || !DateTime.Now.IsDaylightSavingTime()))
                {
                    entry._LastModified += new TimeSpan(1, 0, 0);
                }
                if (!(!entry._LastModified.IsDaylightSavingTime() || DateTime.Now.IsDaylightSavingTime()))
                {
                    entry._LastModified -= new TimeSpan(1, 0, 0);
                }
            }
            entry._LocalFileName     = filename;
            entry._FileNameInArchive = nameInArchive.Replace('\\', '/');
            return(entry);
        }
Example #9
0
        public static ZipDirEntry Read(Stream s, Encoding expectedEncoding)
        {
            int signature = ZipSharedUtilities.ReadSignature(s);

            if (IsNotValidSig(signature))
            {
                s.Seek(-4L, SeekOrigin.Current);
                if (signature != 0x6054b50L)
                {
                    throw new BadReadException(String.Format("  ZipDirEntry::Read(): Bad signature ({0:X8}) at position 0x{1:X8}", signature, s.Position));
                }
                return(null);
            }
            byte[] block = new byte[0x2a];
            if (s.Read(block, 0, block.Length) != block.Length)
            {
                return(null);
            }
            int         i                 = 0;
            ZipDirEntry zde               = new ZipDirEntry();
            short       versionMadeBy     = (short)(block[i++] + (block[i++] * 0x100));
            short       versionNeeded     = (short)(block[i++] + (block[i++] * 0x100));
            short       bitField          = (short)(block[i++] + (block[i++] * 0x100));
            short       compressionMethod = (short)(block[i++] + (block[i++] * 0x100));
            int         lastModDateTime   = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            int         crc32             = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            int         compressedSize    = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            int         uncompressedSize  = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            short       filenameLength    = (short)(block[i++] + (block[i++] * 0x100));
            short       extraFieldLength  = (short)(block[i++] + (block[i++] * 0x100));
            short       commentLength     = (short)(block[i++] + (block[i++] * 0x100));

            i += 2;
            zde._InternalFileAttrs = (short)(block[i++] + (block[i++] * 0x100));
            zde._ExternalFileAttrs = ((block[i++] + (block[i++] * 0x100)) + ((block[i++] * 0x100) * 0x100)) + (((block[i++] * 0x100) * 0x100) * 0x100);
            block = new byte[filenameLength];
            int n = s.Read(block, 0, block.Length);

            if ((bitField & 0x800) == 0x800)
            {
                zde._FileName = ZipSharedUtilities.Utf8StringFromBuffer(block, block.Length);
            }
            else
            {
                zde._FileName = ZipSharedUtilities.StringFromBuffer(block, block.Length, expectedEncoding);
            }
            if (extraFieldLength > 0)
            {
                zde._Extra = new byte[extraFieldLength];
                n          = s.Read(zde._Extra, 0, zde._Extra.Length);
            }
            if (commentLength > 0)
            {
                block = new byte[commentLength];
                n     = s.Read(block, 0, block.Length);
                if ((bitField & 0x800) == 0x800)
                {
                    zde._Comment = ZipSharedUtilities.Utf8StringFromBuffer(block, block.Length);
                }
                else
                {
                    zde._Comment = ZipSharedUtilities.StringFromBuffer(block, block.Length, expectedEncoding);
                }
            }
            return(zde);
        }