Exemplo n.º 1
0
        private void ReadEndOfCentralDirectory()
        {
            try
            {
                this._archiveStream.Seek(-18L, SeekOrigin.End);

                if (!ZipHelper.SeekBackwardsToSignature(this._archiveStream, 101010256U))
                {
                    throw new InvalidDataException(CompressionConstants.EOCDNotFound);
                }

                long position = this._archiveStream.Position;

                ZipEndOfCentralDirectoryBlock eocdBlock;

                ZipEndOfCentralDirectoryBlock.TryReadBlock(this._archiveReader, out eocdBlock);

                if ((int)eocdBlock.NumberOfThisDisk != (int)eocdBlock.NumberOfTheDiskWithTheStartOfTheCentralDirectory)
                {
                    throw new InvalidDataException(CompressionConstants.SplitSpanned);
                }

                this._numberOfThisDisk = (uint)eocdBlock.NumberOfThisDisk;

                this._centralDirectoryStart = (long)eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;

                if ((int)eocdBlock.NumberOfEntriesInTheCentralDirectory != (int)eocdBlock.NumberOfEntriesInTheCentralDirectoryOnThisDisk)
                {
                    throw new InvalidDataException(CompressionConstants.SplitSpanned);
                }

                this._expectedNumberOfEntries = (long)eocdBlock.NumberOfEntriesInTheCentralDirectory;

                if (this._mode == ZipArchiveMode.Update)
                {
                    this._archiveComment = eocdBlock.ArchiveComment;
                }

                if ((int)eocdBlock.NumberOfThisDisk == (int)ushort.MaxValue || (int)eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == -1 || (int)eocdBlock.NumberOfEntriesInTheCentralDirectory == (int)ushort.MaxValue)
                {
                    this._archiveStream.Seek(position - 16L, SeekOrigin.Begin);

                    if (ZipHelper.SeekBackwardsToSignature(this._archiveStream, 117853008U))
                    {
                        Zip64EndOfCentralDirectoryLocator zip64EOCDLocator;

                        Zip64EndOfCentralDirectoryLocator.TryReadBlock(this._archiveReader, out zip64EOCDLocator);

                        if (zip64EOCDLocator.OffsetOfZip64EOCD > 9223372036854775807UL)
                        {
                            throw new InvalidDataException(CompressionConstants.FieldTooBigOffsetToZip64EOCD);
                        }

                        this._archiveStream.Seek((long)zip64EOCDLocator.OffsetOfZip64EOCD, SeekOrigin.Begin);

                        Zip64EndOfCentralDirectoryRecord zip64EOCDRecord;

                        if (!Zip64EndOfCentralDirectoryRecord.TryReadBlock(this._archiveReader, out zip64EOCDRecord))
                        {
                            throw new InvalidDataException(CompressionConstants.Zip64EOCDNotWhereExpected);
                        }

                        this._numberOfThisDisk = zip64EOCDRecord.NumberOfThisDisk;

                        if (zip64EOCDRecord.NumberOfEntriesTotal > 9223372036854775807UL)
                        {
                            throw new InvalidDataException(CompressionConstants.FieldTooBigNumEntries);
                        }

                        if (zip64EOCDRecord.OffsetOfCentralDirectory > 9223372036854775807UL)
                        {
                            throw new InvalidDataException(CompressionConstants.FieldTooBigOffsetToCD);
                        }

                        if ((long)zip64EOCDRecord.NumberOfEntriesTotal != (long)zip64EOCDRecord.NumberOfEntriesOnThisDisk)
                        {
                            throw new InvalidDataException(CompressionConstants.SplitSpanned);
                        }

                        this._expectedNumberOfEntries = (long)zip64EOCDRecord.NumberOfEntriesTotal;

                        this._centralDirectoryStart = (long)zip64EOCDRecord.OffsetOfCentralDirectory;
                    }
                }

                if (this._centralDirectoryStart > this._archiveStream.Length)
                {
                    throw new InvalidDataException(CompressionConstants.FieldTooBigOffsetToCD);
                }
            }
            catch (EndOfStreamException ex)
            {
                throw new InvalidDataException(CompressionConstants.CDCorrupt, (Exception)ex);
            }
            catch (IOException ex)
            {
                throw new InvalidDataException(CompressionConstants.CDCorrupt, (Exception)ex);
            }
        }