/// <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 }
//------------------------------------------------------ // // 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); }
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); }
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); }
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; }
/// <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 }
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); }