Exemple #1
0
 internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd)
 {
     this._archive                      = archive;
     this._originallyInArchive          = true;
     this._diskNumberStart              = cd.DiskNumberStart;
     this._versionToExtract             = (ZipVersionNeededValues)cd.VersionNeededToExtract;
     this._generalPurposeBitFlag        = (ZipArchiveEntry.BitFlagValues)cd.GeneralPurposeBitFlag;
     this.CompressionMethod             = (ZipArchiveEntry.CompressionMethodValues)cd.CompressionMethod;
     this._lastModified                 = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified));
     this._compressedSize               = cd.CompressedSize;
     this._uncompressedSize             = cd.UncompressedSize;
     this._externalFileAttr             = cd.ExternalFileAttributes;
     this._offsetOfLocalHeader          = cd.RelativeOffsetOfLocalHeader;
     this._storedOffsetOfCompressedData = null;
     this._crc32                  = cd.Crc32;
     this._compressedBytes        = null;
     this._storedUncompressedData = null;
     this._currentlyOpenForWrite  = false;
     this._everOpenedForWrite     = false;
     this._outstandingWriteStream = null;
     this.FullName                = this.DecodeEntryName(cd.Filename);
     this._lhUnknownExtraFields   = null;
     this._cdUnknownExtraFields   = cd.ExtraFields;
     this._fileComment            = cd.FileComment;
     this._compressionLevel       = null;
 }
Exemple #2
0
        private void ReadCentralDirectory()
        {
            try
            {
                //assume ReadEndOfCentralDirectory has been called and has populated _centralDirectoryStart

                _archiveStream.Seek(_centralDirectoryStart, SeekOrigin.Begin);

                long numberOfEntries = 0;

                //read the central directory
                ZipCentralDirectoryFileHeader currentHeader;
                bool saveExtraFieldsAndComments = Mode == ZipArchiveMode.Update;
                while (ZipCentralDirectoryFileHeader.TryReadBlock(_archiveReader,
                                                                  saveExtraFieldsAndComments, out currentHeader))
                {
                    AddEntry(new ZipArchiveEntry(this, currentHeader));
                    numberOfEntries++;
                }

                if (numberOfEntries != _expectedNumberOfEntries)
                {
                    throw new InvalidDataException(SR.NumEntriesWrong);
                }
            }
            catch (EndOfStreamException ex)
            {
                throw new InvalidDataException(SR.Format(SR.CentralDirectoryInvalid, ex));
            }
        }
Exemple #3
0
        //Initializes, attaches it to archive
        internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd)
        {
            _archive = archive;

            _originallyInArchive = true;

            _diskNumberStart = cd.DiskNumberStart;
            _versionToExtract = (ZipVersionNeededValues)cd.VersionNeededToExtract;
            _generalPurposeBitFlag = (BitFlagValues)cd.GeneralPurposeBitFlag;
            CompressionMethod = (CompressionMethodValues)cd.CompressionMethod;
            _lastModified = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified));
            _compressedSize = cd.CompressedSize;
            _uncompressedSize = cd.UncompressedSize;
            _offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader;
            /* we don't know this yet: should be _offsetOfLocalHeader + 30 + _storedEntryNameBytes.Length + extrafieldlength
                * but entryname/extra length could be different in LH
                */
            _storedOffsetOfCompressedData = null;
            _crc32 = cd.Crc32;

            _compressedBytes = null;
            _storedUncompressedData = null;
            _currentlyOpenForWrite = false;
            _everOpenedForWrite = false;
            _outstandingWriteStream = null;

            FullName = DecodeEntryName(cd.Filename);

            _lhUnknownExtraFields = null;
            //the cd should have these as null if we aren't in Update mode
            _cdUnknownExtraFields = cd.ExtraFields;
            _fileComment = cd.FileComment;

            _compressionLevel = null;
        }
Exemple #4
0
        //Initializes, attaches it to archive
        internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel)

            : this(archive, cd)
        {
            // Checking of compressionLevel is passed down to DeflateStream and the IDeflater implementation
            // as it is a pugable component that completely encapsulates the meaning of compressionLevel.

            _compressionLevel = compressionLevel;
        }
Exemple #5
0
        // Initializes, attaches it to archive
        internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd)
        {
            _archive = archive;

            _originallyInArchive = true;

            _diskNumberStart            = cd.DiskNumberStart;
            _versionMadeByPlatform      = (ZipVersionMadeByPlatform)cd.VersionMadeByCompatibility;
            _versionMadeBySpecification = (ZipVersionNeededValues)cd.VersionMadeBySpecification;
            _versionToExtract           = (ZipVersionNeededValues)cd.VersionNeededToExtract;
            _generalPurposeBitFlag      = (BitFlagValues)cd.GeneralPurposeBitFlag;
            CompressionMethod           = (CompressionMethodValues)cd.CompressionMethod;
            _lastModified        = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified));
            _compressedSize      = cd.CompressedSize;
            _uncompressedSize    = cd.UncompressedSize;
            _externalFileAttr    = cd.ExternalFileAttributes;
            _offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader;
            // we don't know this yet: should be _offsetOfLocalHeader + 30 + _storedEntryNameBytes.Length + extrafieldlength
            // but entryname/extra length could be different in LH
            _storedOffsetOfCompressedData = null;
            _crc32 = cd.Crc32;

            _compressedBytes        = null;
            _storedUncompressedData = null;
            _currentlyOpenForWrite  = false;
            _everOpenedForWrite     = false;
            _outstandingWriteStream = null;

            FullName = DecodeEntryName(cd.Filename);

            _lhUnknownExtraFields = null;
            // the cd should have these as null if we aren't in Update mode
            _cdUnknownExtraFields = cd.ExtraFields;
            _fileComment          = cd.FileComment;

            _compressionLevel = null;
        }
Exemple #6
0
        private void ReadCentralDirectory()
        {
            ZipCentralDirectoryFileHeader zipCentralDirectoryFileHeader;

            try
            {
                this._archiveStream.Seek(this._centralDirectoryStart, SeekOrigin.Begin);
                long num  = (long)0;
                bool mode = this.Mode == ZipArchiveMode.Update;
                while (ZipCentralDirectoryFileHeader.TryReadBlock(this._archiveReader, mode, out zipCentralDirectoryFileHeader))
                {
                    this.AddEntry(new ZipArchiveEntry(this, zipCentralDirectoryFileHeader));
                    num += (long)1;
                }
                if (num != this._expectedNumberOfEntries)
                {
                    throw new InvalidDataException(Messages.NumEntriesWrong);
                }
            }
            catch (EndOfStreamException endOfStreamException)
            {
                throw new InvalidDataException(Messages.CentralDirectoryInvalid, endOfStreamException);
            }
        }
Exemple #7
0
        // if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null
        // in either case, the zip64 extra field info will be incorporated into other fields
        public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header)
        {
            header = new ZipCentralDirectoryFileHeader();

            if (reader.ReadUInt32() != SignatureConstant)
            {
                return(false);
            }
            header.VersionMadeBySpecification = reader.ReadByte();
            header.VersionMadeByCompatibility = reader.ReadByte();
            header.VersionNeededToExtract     = reader.ReadUInt16();
            header.GeneralPurposeBitFlag      = reader.ReadUInt16();
            header.CompressionMethod          = reader.ReadUInt16();
            header.LastModified = reader.ReadUInt32();
            header.Crc32        = reader.ReadUInt32();
            uint compressedSizeSmall   = reader.ReadUInt32();
            uint uncompressedSizeSmall = reader.ReadUInt32();

            header.FilenameLength    = reader.ReadUInt16();
            header.ExtraFieldLength  = reader.ReadUInt16();
            header.FileCommentLength = reader.ReadUInt16();
            ushort diskNumberStartSmall = reader.ReadUInt16();

            header.InternalFileAttributes = reader.ReadUInt16();
            header.ExternalFileAttributes = reader.ReadUInt32();
            uint relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32();

            header.Filename = reader.ReadBytes(header.FilenameLength);

            bool uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit;
            bool compressedSizeInZip64   = compressedSizeSmall == ZipHelper.Mask32Bit;
            bool relativeOffsetInZip64   = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit;
            bool diskNumberStartInZip64  = diskNumberStartSmall == ZipHelper.Mask16Bit;

            Zip64ExtraField zip64;

            long endExtraFields = reader.BaseStream.Position + header.ExtraFieldLength;

            using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength))
            {
                if (saveExtraFieldsAndComments)
                {
                    header.ExtraFields = ZipGenericExtraField.ParseExtraField(str);
                    zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields,
                                                                   uncompressedSizeInZip64, compressedSizeInZip64,
                                                                   relativeOffsetInZip64, diskNumberStartInZip64);
                }
                else
                {
                    header.ExtraFields = null;
                    zip64 = Zip64ExtraField.GetJustZip64Block(str,
                                                              uncompressedSizeInZip64, compressedSizeInZip64,
                                                              relativeOffsetInZip64, diskNumberStartInZip64);
                }
            }

            // There are zip files that have malformed ExtraField blocks in which GetJustZip64Block() silently bails out without reading all the way to the end
            // of the ExtraField block. Thus we must force the stream's position to the proper place.
            reader.BaseStream.AdvanceToPosition(endExtraFields);

            if (saveExtraFieldsAndComments)
            {
                header.FileComment = reader.ReadBytes(header.FileCommentLength);
            }
            else
            {
                reader.BaseStream.Position += header.FileCommentLength;
                header.FileComment          = null;
            }

            header.UncompressedSize = zip64.UncompressedSize == null
                                                    ? uncompressedSizeSmall
                                                    : zip64.UncompressedSize.Value;
            header.CompressedSize = zip64.CompressedSize == null
                                                    ? compressedSizeSmall
                                                    : zip64.CompressedSize.Value;
            header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null
                                                    ? relativeOffsetOfLocalHeaderSmall
                                                    : zip64.LocalHeaderOffset.Value;
            header.DiskNumberStart = zip64.StartDiskNumber == null
                                                    ? diskNumberStartSmall
                                                    : zip64.StartDiskNumber.Value;

            return(true);
        }
Exemple #8
0
 internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel) : this(archive, cd)
 {
     this._compressionLevel = new CompressionLevel?(compressionLevel);
 }
Exemple #9
0
        //Initializes, attaches it to archive
        internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel)

            : this(archive, cd)
        {
            _compressionLevel = compressionLevel;
        }
Exemple #10
0
        public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header)
        {
            Zip64ExtraField justZip64Block;
            long?           uncompressedSize;
            long            value;
            long            num;
            long            value1;

            header = new ZipCentralDirectoryFileHeader();
            if (reader.ReadUInt32() != 33639248)
            {
                return(false);
            }
            header.VersionMadeBy          = reader.ReadUInt16();
            header.VersionNeededToExtract = reader.ReadUInt16();
            header.GeneralPurposeBitFlag  = reader.ReadUInt16();
            header.CompressionMethod      = reader.ReadUInt16();
            header.LastModified           = reader.ReadUInt32();
            header.Crc32 = reader.ReadUInt32();
            uint num1 = reader.ReadUInt32();
            uint num2 = reader.ReadUInt32();

            header.FilenameLength    = reader.ReadUInt16();
            header.ExtraFieldLength  = reader.ReadUInt16();
            header.FileCommentLength = reader.ReadUInt16();
            ushort num3 = reader.ReadUInt16();

            header.InternalFileAttributes = reader.ReadUInt16();
            header.ExternalFileAttributes = reader.ReadUInt32();
            uint num4 = reader.ReadUInt32();

            header.Filename = reader.ReadBytes((int)header.FilenameLength);
            bool flag     = num2 == -1;
            bool flag1    = num1 == -1;
            bool flag2    = num4 == -1;
            bool flag3    = num3 == 65535;
            long position = (long)(reader.BaseStream.Position + (ulong)header.ExtraFieldLength);

            using (Stream subReadStream = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, (long)header.ExtraFieldLength))
            {
                if (!saveExtraFieldsAndComments)
                {
                    header.ExtraFields = null;
                    justZip64Block     = Zip64ExtraField.GetJustZip64Block(subReadStream, flag, flag1, flag2, flag3);
                }
                else
                {
                    header.ExtraFields = ZipGenericExtraField.ParseExtraField(subReadStream);
                    justZip64Block     = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, flag, flag1, flag2, flag3);
                }
            }
            reader.BaseStream.AdvanceToPosition(position);
            if (!saveExtraFieldsAndComments)
            {
                Stream baseStream = reader.BaseStream;
                baseStream.Position = (long)(baseStream.Position + (ulong)header.FileCommentLength);
                header.FileComment  = null;
            }
            else
            {
                header.FileComment = reader.ReadBytes((int)header.FileCommentLength);
            }
            if (!justZip64Block.UncompressedSize.HasValue)
            {
                value = (long)((ulong)num2);
            }
            else
            {
                uncompressedSize = justZip64Block.UncompressedSize;
                value            = uncompressedSize.Value;
            }
            header.UncompressedSize = value;
            if (!justZip64Block.CompressedSize.HasValue)
            {
                num = (long)((ulong)num1);
            }
            else
            {
                uncompressedSize = justZip64Block.CompressedSize;
                num = uncompressedSize.Value;
            }
            header.CompressedSize = num;
            if (!justZip64Block.LocalHeaderOffset.HasValue)
            {
                value1 = (long)((ulong)num4);
            }
            else
            {
                uncompressedSize = justZip64Block.LocalHeaderOffset;
                value1           = uncompressedSize.Value;
            }
            header.RelativeOffsetOfLocalHeader = value1;
            header.DiskNumberStart             = (!justZip64Block.StartDiskNumber.HasValue ? (int)num3 : justZip64Block.StartDiskNumber.Value);
            return(true);
        }
Exemple #11
0
        //if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null
        //in either case, the zip64 extra field info will be incorporated into other fields
        static public bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header)
        {
            header = new ZipCentralDirectoryFileHeader();

            if (reader.ReadUInt32() != SignatureConstant)
                return false;
            header.VersionMadeBySpecification = reader.ReadByte();
            header.VersionMadeByCompatibility = reader.ReadByte();
            header.VersionNeededToExtract = reader.ReadUInt16();
            header.GeneralPurposeBitFlag = reader.ReadUInt16();
            header.CompressionMethod = reader.ReadUInt16();
            header.LastModified = reader.ReadUInt32();
            header.Crc32 = reader.ReadUInt32();
            uint compressedSizeSmall = reader.ReadUInt32();
            uint uncompressedSizeSmall = reader.ReadUInt32();
            header.FilenameLength = reader.ReadUInt16();
            header.ExtraFieldLength = reader.ReadUInt16();
            header.FileCommentLength = reader.ReadUInt16();
            ushort diskNumberStartSmall = reader.ReadUInt16();
            header.InternalFileAttributes = reader.ReadUInt16();
            header.ExternalFileAttributes = reader.ReadUInt32();
            uint relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32();

            header.Filename = reader.ReadBytes(header.FilenameLength);

            bool uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit;
            bool compressedSizeInZip64 = compressedSizeSmall == ZipHelper.Mask32Bit;
            bool relativeOffsetInZip64 = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit;
            bool diskNumberStartInZip64 = diskNumberStartSmall == ZipHelper.Mask16Bit;

            Zip64ExtraField zip64;

            long endExtraFields = reader.BaseStream.Position + header.ExtraFieldLength;
            using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength))
            {
                if (saveExtraFieldsAndComments)
                {
                    header.ExtraFields = ZipGenericExtraField.ParseExtraField(str);
                    zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields,
                            uncompressedSizeInZip64, compressedSizeInZip64,
                            relativeOffsetInZip64, diskNumberStartInZip64);
                }
                else
                {
                    header.ExtraFields = null;
                    zip64 = Zip64ExtraField.GetJustZip64Block(str,
                            uncompressedSizeInZip64, compressedSizeInZip64,
                            relativeOffsetInZip64, diskNumberStartInZip64);
                }
            }

            // There are zip files that have malformed ExtraField blocks in which GetJustZip64Block() silently bails out without reading all the way to the end
            // of the ExtraField block. Thus we must force the stream's position to the proper place. 
            reader.BaseStream.AdvanceToPosition(endExtraFields);

            if (saveExtraFieldsAndComments)
                header.FileComment = reader.ReadBytes(header.FileCommentLength);
            else
            {
                reader.BaseStream.Position += header.FileCommentLength;
                header.FileComment = null;
            }

            header.UncompressedSize = zip64.UncompressedSize == null
                                                    ? uncompressedSizeSmall
                                                    : zip64.UncompressedSize.Value;
            header.CompressedSize = zip64.CompressedSize == null
                                                    ? compressedSizeSmall
                                                    : zip64.CompressedSize.Value;
            header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null
                                                    ? relativeOffsetOfLocalHeaderSmall
                                                    : zip64.LocalHeaderOffset.Value;
            header.DiskNumberStart = zip64.StartDiskNumber == null
                                                    ? diskNumberStartSmall
                                                    : zip64.StartDiskNumber.Value;

            return true;
        }
Exemple #12
0
        //if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null
        //in either case, the zip64 extra field info will be incorporated into other fields
        static public Boolean TryReadBlock(BinaryReader reader, Boolean saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header)
        {
            header = new ZipCentralDirectoryFileHeader();

            if (reader.ReadUInt32() != SignatureConstant)
            {
                return(false);
            }

            header.VersionMadeBy          = reader.ReadUInt16();
            header.VersionNeededToExtract = reader.ReadUInt16();
            header.GeneralPurposeBitFlag  = reader.ReadUInt16();
            header.CompressionMethod      = reader.ReadUInt16();
            header.LastModified           = reader.ReadUInt32();
            header.Crc32 = reader.ReadUInt32();
            UInt32 compressedSizeSmall   = reader.ReadUInt32();
            UInt32 uncompressedSizeSmall = reader.ReadUInt32();

            header.FilenameLength    = reader.ReadUInt16();
            header.ExtraFieldLength  = reader.ReadUInt16();
            header.FileCommentLength = reader.ReadUInt16();
            UInt16 diskNumberStartSmall = reader.ReadUInt16();

            header.InternalFileAttributes = reader.ReadUInt16();
            header.ExternalFileAttributes = reader.ReadUInt32();
            UInt32 relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32();

            header.Filename = reader.ReadBytes(header.FilenameLength);

            Boolean uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit;
            Boolean compressedSizeInZip64   = compressedSizeSmall == ZipHelper.Mask32Bit;
            Boolean relativeOffsetInZip64   = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit;
            Boolean diskNumberStartInZip64  = diskNumberStartSmall == ZipHelper.Mask16Bit;

            Zip64ExtraField zip64;

            using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength))
            {
                if (saveExtraFieldsAndComments)
                {
                    header.ExtraFields = ZipGenericExtraField.ParseExtraField(str);
                    zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields,
                                                                   uncompressedSizeInZip64, compressedSizeInZip64,
                                                                   relativeOffsetInZip64, diskNumberStartInZip64);
                }
                else
                {
                    header.ExtraFields = null;
                    zip64 = Zip64ExtraField.GetJustZip64Block(str,
                                                              uncompressedSizeInZip64, compressedSizeInZip64,
                                                              relativeOffsetInZip64, diskNumberStartInZip64);
                }
            }

            if (saveExtraFieldsAndComments)
            {
                header.FileComment = reader.ReadBytes(header.FileCommentLength);
            }
            else
            {
                reader.BaseStream.Position += header.FileCommentLength;
                header.FileComment          = null;
            }

            header.UncompressedSize = zip64.UncompressedSize == null
                                                    ? uncompressedSizeSmall
                                                    : zip64.UncompressedSize.Value;
            header.CompressedSize = zip64.CompressedSize == null
                                                    ? compressedSizeSmall
                                                    : zip64.CompressedSize.Value;
            header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null
                                                    ? relativeOffsetOfLocalHeaderSmall
                                                    : zip64.LocalHeaderOffset.Value;
            header.DiskNumberStart = zip64.StartDiskNumber == null
                                                    ? diskNumberStartSmall
                                                    : zip64.StartDiskNumber.Value;

            return(true);
        }