Пример #1
0
        /// <summary>
        /// Validate
        /// </summary>
        /// <param name="fileName">pre-trimmed and normalized filename (see ValidateNormalizeFileName)</param>
        /// <param name="centralDir">central directory block</param>
        /// <param name="centralDirFileHeader">file header from central directory</param>
        private void Validate(string fileName,
                              ZipIOCentralDirectoryBlock centralDir,
                              ZipIOCentralDirectoryFileHeader centralDirFileHeader)
        {
            // check that name matches parameter in a case sensitive culture neutral way
            if (0 != String.CompareOrdinal(_localFileHeader.FileName, fileName))
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            // compare compressed and uncompressed sizes, crc from central directory
            if ((VersionNeededToExtract != centralDirFileHeader.VersionNeededToExtract) ||
                (GeneralPurposeBitFlag != centralDirFileHeader.GeneralPurposeBitFlag) ||
                (CompressedSize != centralDirFileHeader.CompressedSize) ||
                (UncompressedSize != centralDirFileHeader.UncompressedSize) ||
                (CompressionMethod != centralDirFileHeader.CompressionMethod) ||
                (Crc32 != centralDirFileHeader.Crc32))
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            // check for read into central directory (which would indicate file corruption)
            if (Offset + Size > centralDir.Offset)
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            // No CRC check here
            // delay validating the actual CRC until it is possible to do so without additional read operations
            // This is only for non-streaming mode (at this point we only support creation not consumption)
            // This is to avoid the forced reading of entire stream just for CRC check
            // CRC check is delegated  to ProgressiveCrcCalculatingStream and CRC is only validated
            //  once calculated CRC is available. This implies that CRC check operation is not
            //  guaranteed to be performed
        }
Пример #2
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        internal static ZipIOLocalFileBlock SeekableLoad(ZipIOBlockManager blockManager,
                                                         string fileName)
        {
            Debug.Assert(!blockManager.Streaming);
            Debug.Assert(blockManager.CentralDirectoryBlock.FileExists(fileName));

            // Get info from the central directory
            ZipIOCentralDirectoryBlock      centralDir           = blockManager.CentralDirectoryBlock;
            ZipIOCentralDirectoryFileHeader centralDirFileHeader = centralDir.GetCentralDirectoryFileHeader(fileName);

            long localHeaderOffset = centralDirFileHeader.OffsetOfLocalHeader;
            bool folderFlag        = centralDirFileHeader.FolderFlag;
            bool volumeLabelFlag   = centralDirFileHeader.VolumeLabelFlag;

            blockManager.Stream.Seek(localHeaderOffset, SeekOrigin.Begin);

            ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, folderFlag, volumeLabelFlag);

            block.ParseRecord(
                blockManager.BinaryReader,
                fileName,
                localHeaderOffset,
                centralDir,
                centralDirFileHeader);

            return(block);
        }
Пример #3
0
        private void ParseRecord(BinaryReader reader,
                                 string fileName,
                                 long position,
                                 ZipIOCentralDirectoryBlock centralDir,
                                 ZipIOCentralDirectoryFileHeader centralDirFileHeader)
        {
            CheckDisposed();
            Debug.Assert(!_blockManager.Streaming, "Not legal in Streaming mode");

            _localFileHeader = ZipIOLocalFileHeader.ParseRecord(reader, _blockManager.Encoding);

            // Let's find out whether local file descriptor is there or not
            if (_localFileHeader.StreamingCreationFlag)
            {
                // seek forward by the uncompressed size
                _blockManager.Stream.Seek(centralDirFileHeader.CompressedSize, SeekOrigin.Current);
                _localFileDataDescriptor = ZipIOLocalFileDataDescriptor.ParseRecord(reader,
                                                                                    centralDirFileHeader.CompressedSize,
                                                                                    centralDirFileHeader.UncompressedSize,
                                                                                    centralDirFileHeader.Crc32,
                                                                                    _localFileHeader.VersionNeededToExtract);
            }
            else
            {
                _localFileDataDescriptor = null;
            }

            _offset    = position;
            _dirtyFlag = false;

            checked
            {
                _fileItemStream = new ZipIOFileItemStream(_blockManager,
                                                          this,
                                                          position + _localFileHeader.Size,
                                                          centralDirFileHeader.CompressedSize);
            }

            // init deflate stream if necessary
            if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Deflated)
            {
                Debug.Assert(_fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero");
                _deflateStream = new CompressStream(_fileItemStream, centralDirFileHeader.UncompressedSize);

                _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _deflateStream, Crc32);
            }
            else if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Stored)
            {
                _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _fileItemStream, Crc32);
            }
            else
            {
                throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedCompressionMethod));
            }

            Validate(fileName, centralDir, centralDirFileHeader);
        }
Пример #4
0
        internal static ZipIOCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager)
        {
            ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);

            block._offset = 0;              // it just an initial value, that will be adjusted later
            // it doesn't matter whether this offset overlaps anything or not

            block._dirtyFlag = true;

            // this dig sig is optional if we ever wanted to make this record, we would need to call
            //       ZipIOCentralDirectoryDigitalSignature.CreateNew();
            block._centralDirectoryDigitalSignature = null;

            return(block);
        }
Пример #5
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        internal static ZipIOCentralDirectoryBlock SeekableLoad(ZipIOBlockManager blockManager)
        {
            // get proper values from  zip 64 records request will be redirected to the
            // regular EOCD if ZIP 64 record wasn't originated from the parsing

            ZipIOZip64EndOfCentralDirectoryBlock zip64EOCD = blockManager.Zip64EndOfCentralDirectoryBlock;

            blockManager.Stream.Seek(zip64EOCD.OffsetOfStartOfCentralDirectory, SeekOrigin.Begin);

            ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);

            block.ParseRecord(blockManager.BinaryReader,
                              zip64EOCD.OffsetOfStartOfCentralDirectory,
                              zip64EOCD.TotalNumberOfEntriesInTheCentralDirectory,
                              zip64EOCD.SizeOfCentralDirectory);

            return(block);
        }
        internal static ZipIOCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager)          
        {
            ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);

            block._offset = 0;              // it just an initial value, that will be adjusted later 
                                                   // it doesn't matter whether this offset overlaps anything or not 
                                                            
            block._dirtyFlag = true;

            // this dig sig is optional if we ever wanted to make this record, we would need to call
            //       ZipIOCentralDirectoryDigitalSignature.CreateNew();
            block._centralDirectoryDigitalSignature = null;  

            return block;
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        internal static ZipIOCentralDirectoryBlock SeekableLoad(ZipIOBlockManager blockManager)
        {
            // get proper values from  zip 64 records request will be redirected to the 
            // regular EOCD if ZIP 64 record wasn't originated from the parsing 

            ZipIOZip64EndOfCentralDirectoryBlock zip64EOCD = blockManager.Zip64EndOfCentralDirectoryBlock;
        
            blockManager.Stream.Seek(zip64EOCD.OffsetOfStartOfCentralDirectory, SeekOrigin.Begin);

            ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);
            
            block.ParseRecord(blockManager.BinaryReader, 
                                            zip64EOCD.OffsetOfStartOfCentralDirectory, 
                                            zip64EOCD.TotalNumberOfEntriesInTheCentralDirectory,
                                            zip64EOCD.SizeOfCentralDirectory);

            return block;
        }
Пример #8
0
        /// <summary> 
        /// Validate
        /// </summary> 
        /// <param name="fileName">pre-trimmed and normalized filename (see ValidateNormalizeFileName)</param>
        /// <param name="centralDir">central directory block</param>
        /// <param name="centralDirFileHeader">file header from central directory</param>
        private void Validate(string fileName, 
            ZipIOCentralDirectoryBlock centralDir,
            ZipIOCentralDirectoryFileHeader centralDirFileHeader) 
        { 
            // check that name matches parameter in a case sensitive culture neutral way
            if (0 != String.CompareOrdinal(_localFileHeader.FileName, fileName)) 
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }
 
            // compare compressed and uncompressed sizes, crc from central directory
            if ((VersionNeededToExtract != centralDirFileHeader.VersionNeededToExtract) || 
                (GeneralPurposeBitFlag != centralDirFileHeader.GeneralPurposeBitFlag) || 
                (CompressedSize != centralDirFileHeader.CompressedSize) ||
                (UncompressedSize != centralDirFileHeader.UncompressedSize) || 
                (CompressionMethod != centralDirFileHeader.CompressionMethod) ||
                (Crc32 != centralDirFileHeader.Crc32))
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData)); 
            }
 
            // check for read into central directory (which would indicate file corruption) 
            if (Offset + Size > centralDir.Offset)
                throw new FileFormatException(SR.Get(SRID.CorruptedData)); 

            // No CRC check here
            // delay validating the actual CRC until it is possible to do so without additional read operations
            // This is only for non-streaming mode (at this point we only support creation not consumption) 
            // This is to avoid the forced reading of entire stream just for CRC check
            // CRC check is delegated  to ProgressiveCrcCalculatingStream and CRC is only validated 
            //  once calculated CRC is available. This implies that CRC check operation is not 
            //  guaranteed to be performed
        } 
Пример #9
0
        private void ParseRecord (BinaryReader reader,
                                            string fileName,
                                            long position, 
                                            ZipIOCentralDirectoryBlock centralDir,
                                            ZipIOCentralDirectoryFileHeader centralDirFileHeader) 
        { 
            CheckDisposed();
            Debug.Assert(!_blockManager.Streaming, "Not legal in Streaming mode"); 

            _localFileHeader = ZipIOLocalFileHeader.ParseRecord(reader, _blockManager.Encoding);

            // Let's find out whether local file descriptor is there or not 
            if (_localFileHeader.StreamingCreationFlag)
            { 
                // seek forward by the uncompressed size 
                _blockManager.Stream.Seek(centralDirFileHeader.CompressedSize, SeekOrigin.Current);
                _localFileDataDescriptor = ZipIOLocalFileDataDescriptor.ParseRecord(reader, 
                                                        centralDirFileHeader.CompressedSize,
                                                        centralDirFileHeader.UncompressedSize,
                                                        centralDirFileHeader.Crc32,
                                                        _localFileHeader.VersionNeededToExtract); 
            }
            else 
            { 
                _localFileDataDescriptor = null;
            } 

            _offset = position;
            _dirtyFlag = false;
 
            checked
            { 
                _fileItemStream = new ZipIOFileItemStream(_blockManager, 
                                            this,
                                            position + _localFileHeader.Size, 
                                            centralDirFileHeader.CompressedSize);
            }

            // init deflate stream if necessary 
            if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Deflated)
            { 
                Debug.Assert(_fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero"); 
                _deflateStream = new CompressStream(_fileItemStream, centralDirFileHeader.UncompressedSize);
 
                _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _deflateStream, Crc32);
            }
            else if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Stored)
            { 
                _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _fileItemStream, Crc32);
            } 
            else 
            {
                throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedCompressionMethod)); 
            }

            Validate(fileName, centralDir, centralDirFileHeader);
 
        }