// used in streaming case
        internal static ZipIOLocalFileDataDescriptor CreateNew()
        {
            ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();
            descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;

            return descriptor;
        }
        // used in streaming case
        internal static ZipIOLocalFileDataDescriptor CreateNew()
        {
            ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();

            descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;

            return(descriptor);
        }
Esempio n. 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);
        }
Esempio n. 4
0
        internal static ZipIOLocalFileBlock CreateNew(ZipIOBlockManager blockManager,
                                                      string fileName,
                                                      CompressionMethodEnum compressionMethod,
                                                      DeflateOptionEnum deflateOption)
        {
            //this should be ensured by the higher levels
            Debug.Assert(Enum.IsDefined(typeof(CompressionMethodEnum), compressionMethod));
            Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), deflateOption));

            ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, false, false);

            block._localFileHeader = ZipIOLocalFileHeader.CreateNew
                                         (fileName,
                                         blockManager.Encoding,
                                         compressionMethod,
                                         deflateOption, blockManager.Streaming);

            // if in streaming mode - force to Zip64 mode in case the streams get large
            if (blockManager.Streaming)
            {
                block._localFileDataDescriptor = ZipIOLocalFileDataDescriptor.CreateNew();
            }

            block._offset    = 0; // intial value, that is not too important for the brand new File item
            block._dirtyFlag = true;

            block._fileItemStream = new  ZipIOFileItemStream(blockManager,
                                                             block,
                                                             block._offset + block._localFileHeader.Size,
                                                             0);

            // create deflate wrapper if necessary
            if (compressionMethod == CompressionMethodEnum.Deflated)
            {
                Debug.Assert(block._fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero");
                // Pass bool to indicate that this stream is "new" and must be dirty so that
                // the valid empty deflate stream is emitted (2-byte sequence - see CompressStream for details).
                block._deflateStream = new CompressStream(block._fileItemStream, 0, true);

                block._crcCalculatingStream = new ProgressiveCrcCalculatingStream(blockManager, block._deflateStream);
            }
            else
            {
                block._crcCalculatingStream = new ProgressiveCrcCalculatingStream(blockManager, block._fileItemStream);
            }

            return(block);
        }
        internal static ZipIOLocalFileDataDescriptor ParseRecord(BinaryReader reader,
                                                                 long compressedSizeFromCentralDir,
                                                                 long uncompressedSizeFromCentralDir,
                                                                 UInt32 crc32FromCentralDir,
                                                                 UInt16 versionNeededToExtract)
        {
            ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();

            // There are 4 distinct scenario we would like to support
            //   1.based on the appnote it seems that the structure of this record is following:
            //                  crc-32                          4 bytes
            //                  compressed size                 4 bytes (scenario 1.a has 8 bytes)
            //                  uncompressed size               4 bytes (scenario 1.a has 8 bytes)
            //
            //   2.based on files that we have been able to examine
            //                  data descriptor signature        4 bytes  (0x08074b50)
            //                  crc-32                                  4 bytes
            //                  compressed size                   4 bytes (scenario 2.a has 8 bytes)
            //                  uncompressed size               4 bytes (scenario 2.a has 8 bytes)
            //
            // we can safely assume that this record is not the last one in the file, so let's just
            // read the max Bytes required to store the largest structure , and compare results

            // at most we are looking at 6 * 4  = 24 bytes
            UInt32[] buffer = new UInt32[6];

            // let's try to match the smallest possible structure (3 x 4) 32 bit without signature
            buffer[0] = reader.ReadUInt32();
            buffer[1] = reader.ReadUInt32();
            buffer[2] = reader.ReadUInt32();

            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     _signatureConstant,
                                     buffer[0],
                                     buffer[1],
                                     buffer[2]))
            {
                descriptor._size = _fixedMinimalRecordSizeWithoutSignature;
                return(descriptor);
            }

            // let's try to match the next record size (4 x 4) 32 bit with signature
            buffer[3] = reader.ReadUInt32();
            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     buffer[0],
                                     buffer[1],
                                     buffer[2],
                                     buffer[3]))
            {
                descriptor._size = _fixedMinimalRecordSizeWithSignature;
                return(descriptor);
            }

            // At this point prior to trying to match 64 bit structures we need to make sure that version is high enough
            if (versionNeededToExtract < (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat)
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            //let's try to match the 64 bit structures 64 bit without signature
            buffer[4] = reader.ReadUInt32();
            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     _signatureConstant,
                                     buffer[0],
                                     ZipIOBlockManager.ConvertToUInt64(buffer[1], buffer[2]),
                                     ZipIOBlockManager.ConvertToUInt64(buffer[3], buffer[4])))
            {
                descriptor._size = _fixedMinimalRecordSizeWithoutSignatureZip64;
                return(descriptor);
            }

            //let's try to match the 64 bit structures 64 bit with signature
            buffer[5] = reader.ReadUInt32();
            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     buffer[0],
                                     buffer[1],
                                     ZipIOBlockManager.ConvertToUInt64(buffer[2], buffer[3]),
                                     ZipIOBlockManager.ConvertToUInt64(buffer[4], buffer[5])))
            {
                descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;
                return(descriptor);
            }

            // we couldn't match anything at this point we need to fail
            throw new FileFormatException(SR.Get(SRID.CorruptedData));
        }
        internal static ZipIOLocalFileDataDescriptor ParseRecord(BinaryReader reader,  
                                    long compressedSizeFromCentralDir, 
                                    long uncompressedSizeFromCentralDir,
                                    UInt32 crc32FromCentralDir,
                                    UInt16 versionNeededToExtract)
        {
            ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();

            // There are 4 distinct scenario we would like to support 
            //   1.based on the appnote it seems that the structure of this record is following:
            //                  crc-32                          4 bytes
            //                  compressed size                 4 bytes (scenario 1.a has 8 bytes)
            //                  uncompressed size               4 bytes (scenario 1.a has 8 bytes)
            //
            //   2.based on files that we have been able to examine 
            //                  data descriptor signature        4 bytes  (0x08074b50)
            //                  crc-32                                  4 bytes
            //                  compressed size                   4 bytes (scenario 2.a has 8 bytes)
            //                  uncompressed size               4 bytes (scenario 2.a has 8 bytes)
            //
            // we can safely assume that this record is not the last one in the file, so let's just 
            // read the max Bytes required to store the largest structure , and compare results 

            // at most we are looking at 6 * 4  = 24 bytes      
            UInt32[] buffer = new UInt32[6];

            // let's try to match the smallest possible structure (3 x 4) 32 bit without signature 
            buffer[0] = reader.ReadUInt32(); 
            buffer[1] = reader.ReadUInt32(); 
            buffer[2] = reader.ReadUInt32(); 

            if (descriptor.TestMatch(_signatureConstant, 
                                    crc32FromCentralDir,
                                    compressedSizeFromCentralDir, 
                                    uncompressedSizeFromCentralDir,
                               _signatureConstant,      
                                    buffer[0],
                                    buffer[1],
                                    buffer[2]))
            {
                descriptor._size = _fixedMinimalRecordSizeWithoutSignature;
                return descriptor;
            }

            // let's try to match the next record size (4 x 4) 32 bit with signature 
            buffer[3] = reader.ReadUInt32(); 
            if (descriptor.TestMatch(_signatureConstant, 
                                    crc32FromCentralDir,
                                    compressedSizeFromCentralDir, 
                                    uncompressedSizeFromCentralDir,
                                 buffer[0],      
                                    buffer[1],
                                    buffer[2],
                                    buffer[3]))
            {
                descriptor._size = _fixedMinimalRecordSizeWithSignature;
                return descriptor;
            }

            // At this point prior to trying to match 64 bit structures we need to make sure that version is high enough 
            if (versionNeededToExtract <  (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat)
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            //let's try to match the 64 bit structures 64 bit without signature 
            buffer[4] = reader.ReadUInt32();             
            if (descriptor.TestMatch(_signatureConstant, 
                                    crc32FromCentralDir,
                                    compressedSizeFromCentralDir, 
                                    uncompressedSizeFromCentralDir,
                                 _signatureConstant,      
                                    buffer[0],
                                    ZipIOBlockManager.ConvertToUInt64(buffer[1], buffer[2]),
                                    ZipIOBlockManager.ConvertToUInt64(buffer[3], buffer[4])))
            {
                descriptor._size = _fixedMinimalRecordSizeWithoutSignatureZip64;
                return descriptor;
            }            

            //let's try to match the 64 bit structures 64 bit with signature 
            buffer[5] = reader.ReadUInt32();             
            if (descriptor.TestMatch(_signatureConstant, 
                                    crc32FromCentralDir,
                                    compressedSizeFromCentralDir, 
                                    uncompressedSizeFromCentralDir,
                                 buffer[0],      
                                    buffer[1],
                                    ZipIOBlockManager.ConvertToUInt64(buffer[2], buffer[3]),
                                    ZipIOBlockManager.ConvertToUInt64(buffer[4], buffer[5])))
            {
                descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;
                return descriptor;
            }   

            // we couldn't match anything at this point we need to fail 
            throw new FileFormatException(SR.Get(SRID.CorruptedData));
        }