Exemplo n.º 1
0
        internal static ZipIOLocalFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
        {
            ZipIOLocalFileHeader header = new ZipIOLocalFileHeader();

            header._signature = reader.ReadUInt32();
            header._versionNeededToExtract = reader.ReadUInt16();
            header._generalPurposeBitFlag  = reader.ReadUInt16();
            header._compressionMethod      = reader.ReadUInt16();
            header._lastModFileDateTime    = reader.ReadUInt32();
            header._crc32            = reader.ReadUInt32();
            header._compressedSize   = reader.ReadUInt32();
            header._uncompressedSize = reader.ReadUInt32();
            header._fileNameLength   = reader.ReadUInt16();
            header._extraFieldLength = reader.ReadUInt16();
            header._fileName         = reader.ReadBytes(header._fileNameLength);
            ZipIOZip64ExtraFieldUsage none = ZipIOZip64ExtraFieldUsage.None;

            if (header._versionNeededToExtract >= 0x2d)
            {
                if (header._compressedSize == uint.MaxValue)
                {
                    none |= ZipIOZip64ExtraFieldUsage.CompressedSize;
                }
                if (header._uncompressedSize == uint.MaxValue)
                {
                    none |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
                }
            }
            header._extraField     = ZipIOExtraField.ParseRecord(reader, none, header._extraFieldLength);
            header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));
            header.Validate();
            return(header);
        }
        internal static ZipIOCentralDirectoryFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
        {
            ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);

            header._signature              = reader.ReadUInt32();
            header._versionMadeBy          = reader.ReadUInt16();
            header._versionNeededToExtract = reader.ReadUInt16();
            header._generalPurposeBitFlag  = reader.ReadUInt16();
            header._compressionMethod      = reader.ReadUInt16();
            header._lastModFileDateTime    = reader.ReadUInt32();
            header._crc32                       = reader.ReadUInt32();
            header._compressedSize              = reader.ReadUInt32();
            header._uncompressedSize            = reader.ReadUInt32();
            header._fileNameLength              = reader.ReadUInt16();
            header._extraFieldLength            = reader.ReadUInt16();
            header._fileCommentLength           = reader.ReadUInt16();
            header._diskNumberStart             = reader.ReadUInt16();
            header._internalFileAttributes      = reader.ReadUInt16();
            header._externalFileAttributes      = reader.ReadUInt32();
            header._relativeOffsetOfLocalHeader = reader.ReadUInt32();

            header._fileName = reader.ReadBytes(header._fileNameLength);

            // check for the ZIP 64 version and escaped values
            ZipIOZip64ExtraFieldUsage zip64extraFieldUsage = ZipIOZip64ExtraFieldUsage.None;

            if (header._versionNeededToExtract >= (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat)
            {
                if (header._compressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
                }
                if (header._uncompressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
                }
                if (header._relativeOffsetOfLocalHeader == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader;
                }
                if (header._diskNumberStart == UInt16.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.DiskNumber;
                }
            }

            // if the ZIP 64 record is missing the zip64extraFieldUsage value will be ignored
            header._extraField = ZipIOExtraField.ParseRecord(reader,
                                                             zip64extraFieldUsage,
                                                             header._extraFieldLength);

            header._fileComment = reader.ReadBytes(header._fileCommentLength);

            //populate frequently used field with user friendly data representations
            header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));

            header.Validate();

            return(header);
        }
Exemplo n.º 3
0
        internal static ZipIOExtraField ParseRecord(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage, ushort expectedExtraFieldSize)
        {
            if (expectedExtraFieldSize == 0)
            {
                if (zip64extraFieldUsage != ZipIOZip64ExtraFieldUsage.None)
                {
                    throw new FileFormatException(SR.Get("CorruptedData"));
                }
                return(CreateNew(false));
            }
            ZipIOExtraField field = new ZipIOExtraField();

            while (expectedExtraFieldSize > 0)
            {
                if (expectedExtraFieldSize < ZipIOExtraFieldElement.MinimumSize)
                {
                    throw new FileFormatException(SR.Get("CorruptedData"));
                }
                ZipIOExtraFieldElement        element  = ZipIOExtraFieldElement.Parse(reader, zip64extraFieldUsage);
                ZipIOExtraFieldZip64Element   element3 = element as ZipIOExtraFieldZip64Element;
                ZipIOExtraFieldPaddingElement element2 = element as ZipIOExtraFieldPaddingElement;
                if (element3 != null)
                {
                    if (field._zip64Element != null)
                    {
                        throw new FileFormatException(SR.Get("CorruptedData"));
                    }
                    field._zip64Element = element3;
                }
                else if (element2 != null)
                {
                    if (field._paddingElement != null)
                    {
                        throw new FileFormatException(SR.Get("CorruptedData"));
                    }
                    field._paddingElement = element2;
                }
                else
                {
                    if (field._extraFieldElements == null)
                    {
                        field._extraFieldElements = new ArrayList(3);
                    }
                    field._extraFieldElements.Add(element);
                }
                expectedExtraFieldSize = (ushort)(expectedExtraFieldSize - element.Size);
            }
            if (expectedExtraFieldSize != 0)
            {
                throw new FileFormatException(SR.Get("CorruptedData"));
            }
            if (field._zip64Element == null)
            {
                field._zip64Element = ZipIOExtraFieldZip64Element.CreateNew();
            }
            return(field);
        }
Exemplo n.º 4
0
        internal static ZipIOExtraFieldElement Parse(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage)
        {
            // we can safely parse the Id and Size here
            //  since the minimum size is checked from the caller (ZipIoExtraField)
            UInt16 id   = reader.ReadUInt16();
            UInt16 size = reader.ReadUInt16();

            ZipIOExtraFieldElement newElement;

            if (id == ZipIOExtraFieldZip64Element.ConstantFieldId)  // Found Zip64 Extra Field element
            {
                newElement = new ZipIOExtraFieldZip64Element();
                ((ZipIOExtraFieldZip64Element)newElement).Zip64ExtraFieldUsage = zip64extraFieldUsage;
            }
            else if (id == ZipIOExtraFieldPaddingElement.ConstantFieldId)   // Found potential Padding Extra Field element
            {
                // Even if the id matches Padding Extra Element id, we cannot be sure if it is Microsoft defined one
                // until its signature is verified

                // This extra field matches Padding Extra Element id, but it is not big enough to be ours
                if (size < ZipIOExtraFieldPaddingElement.MinimumFieldDataSize)
                {
                    // Treat it as an unknown Extra Field element
                    newElement = new ZipIOExtraFieldElement(id);
                }
                else
                {
                    // Sniff bytes to check it it matches our Padding extra field signature
                    byte[] sniffedBytes = reader.ReadBytes(ZipIOExtraFieldPaddingElement.SignatureSize);
                    if (ZipIOExtraFieldPaddingElement.MatchesPaddingSignature(sniffedBytes))
                    {
                        // Signature matches the Padding Extra Field signature
                        newElement = new ZipIOExtraFieldPaddingElement();
                    }
                    else
                    {
                        // Signature doesn't match; treat it a an unknown Extra Field element
                        newElement = new ZipIOExtraFieldElement(id, sniffedBytes);
                    }
                }
            }
            else
            {
                newElement = new ZipIOExtraFieldElement(id);
            }

            // Parse the data field of the Extra Field element
            newElement.ParseDataField(reader, size);

            return(newElement);
        }
Exemplo n.º 5
0
        internal static ZipIOExtraFieldElement Parse(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage)
        {
            // we can safely parse the Id and Size here
            //  since the minimum size is checked from the caller (ZipIoExtraField)
            UInt16 id = reader.ReadUInt16();
            UInt16 size = reader.ReadUInt16();

            ZipIOExtraFieldElement newElement;

            if (id == ZipIOExtraFieldZip64Element.ConstantFieldId)  // Found Zip64 Extra Field element
            {
                newElement = new ZipIOExtraFieldZip64Element();
                ((ZipIOExtraFieldZip64Element) newElement).Zip64ExtraFieldUsage = zip64extraFieldUsage;
            }
            else if (id == ZipIOExtraFieldPaddingElement.ConstantFieldId)   // Found potential Padding Extra Field element
            {
                // Even if the id matches Padding Extra Element id, we cannot be sure if it is Microsoft defined one
                // until its signature is verified

                // This extra field matches Padding Extra Element id, but it is not big enough to be ours
                if (size < ZipIOExtraFieldPaddingElement.MinimumFieldDataSize)
                {
                    // Treat it as an unknown Extra Field element
                    newElement = new ZipIOExtraFieldElement(id);
                }
                else
                {
                    // Sniff bytes to check it it matches our Padding extra field signature
                    byte[] sniffedBytes = reader.ReadBytes(ZipIOExtraFieldPaddingElement.SignatureSize);
                    if (ZipIOExtraFieldPaddingElement.MatchesPaddingSignature(sniffedBytes))
                    {
                        // Signature matches the Padding Extra Field signature
                        newElement = new ZipIOExtraFieldPaddingElement();
                    }
                    else
                    {
                        // Signature doesn't match; treat it a an unknown Extra Field element
                        newElement = new ZipIOExtraFieldElement(id, sniffedBytes);
                    }
                }
            }
            else
            {
                newElement = new ZipIOExtraFieldElement(id);
            }

            // Parse the data field of the Extra Field element
            newElement.ParseDataField(reader, size);

            return newElement;
        }
        internal static ZipIOCentralDirectoryFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
        {
            ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);

            header._signature              = reader.ReadUInt32();
            header._versionMadeBy          = reader.ReadUInt16();
            header._versionNeededToExtract = reader.ReadUInt16();
            header._generalPurposeBitFlag  = reader.ReadUInt16();
            header._compressionMethod      = reader.ReadUInt16();
            header._lastModFileDateTime    = reader.ReadUInt32();
            header._crc32                       = reader.ReadUInt32();
            header._compressedSize              = reader.ReadUInt32();
            header._uncompressedSize            = reader.ReadUInt32();
            header._fileNameLength              = reader.ReadUInt16();
            header._extraFieldLength            = reader.ReadUInt16();
            header._fileCommentLength           = reader.ReadUInt16();
            header._diskNumberStart             = reader.ReadUInt16();
            header._internalFileAttributes      = reader.ReadUInt16();
            header._externalFileAttributes      = reader.ReadUInt32();
            header._relativeOffsetOfLocalHeader = reader.ReadUInt32();
            header._fileName                    = reader.ReadBytes(header._fileNameLength);
            ZipIOZip64ExtraFieldUsage none = ZipIOZip64ExtraFieldUsage.None;

            if (header._versionNeededToExtract >= 0x2d)
            {
                if (header._compressedSize == uint.MaxValue)
                {
                    none |= ZipIOZip64ExtraFieldUsage.CompressedSize;
                }
                if (header._uncompressedSize == uint.MaxValue)
                {
                    none |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
                }
                if (header._relativeOffsetOfLocalHeader == uint.MaxValue)
                {
                    none |= ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader;
                }
                if (header._diskNumberStart == 0xffff)
                {
                    none |= ZipIOZip64ExtraFieldUsage.DiskNumber;
                }
            }
            header._extraField     = ZipIOExtraField.ParseRecord(reader, none, header._extraFieldLength);
            header._fileComment    = reader.ReadBytes(header._fileCommentLength);
            header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));
            header.Validate();
            return(header);
        }
Exemplo n.º 7
0
        internal static ZipIOExtraFieldElement Parse(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage)
        {
            ZipIOExtraFieldElement element;
            ushort id   = reader.ReadUInt16();
            ushort size = reader.ReadUInt16();

            if (id == ZipIOExtraFieldZip64Element.ConstantFieldId)
            {
                element = new ZipIOExtraFieldZip64Element();
                ((ZipIOExtraFieldZip64Element)element).Zip64ExtraFieldUsage = zip64extraFieldUsage;
            }
            else if (id == ZipIOExtraFieldPaddingElement.ConstantFieldId)
            {
                if (size < ZipIOExtraFieldPaddingElement.MinimumFieldDataSize)
                {
                    element = new ZipIOExtraFieldElement(id);
                }
                else
                {
                    byte[] sniffiedBytes = reader.ReadBytes(ZipIOExtraFieldPaddingElement.SignatureSize);
                    if (ZipIOExtraFieldPaddingElement.MatchesPaddingSignature(sniffiedBytes))
                    {
                        element = new ZipIOExtraFieldPaddingElement();
                    }
                    else
                    {
                        element = new ZipIOExtraFieldElement(id, sniffiedBytes);
                    }
                }
            }
            else
            {
                element = new ZipIOExtraFieldElement(id);
            }
            element.ParseDataField(reader, size);
            return(element);
        }
Exemplo n.º 8
0
 // Methods
 internal ZipIOExtraFieldZip64Element()
     : base(1)
 {
     this._zip64ExtraFieldUsage = ZipIOZip64ExtraFieldUsage.None;
 }
Exemplo n.º 9
0
        internal static ZipIOExtraField ParseRecord(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage, ushort expectedExtraFieldSize)
        {
            // most of the files are not ZIP 64, and instead of trying to parse it we should create new empty record
            if (expectedExtraFieldSize == 0)
            {
                if (zip64extraFieldUsage != ZipIOZip64ExtraFieldUsage.None)
                {
                    // in case there is an expectation by the caller for a non empty record we should throw
                    throw new FileFormatException(SR.Get(SRID.CorruptedData));
                }

                // We are creating Extra Fields for the existing Local File Header,
                //  so no need to create a new padding field
                return(CreateNew(false));
            }

            ZipIOExtraField extraField = new ZipIOExtraField();

            // Parse all Extra elements from Extra Field
            while (expectedExtraFieldSize > 0)
            {
                if (expectedExtraFieldSize < ZipIOExtraFieldElement.MinimumSize)
                {
                    throw new FileFormatException(SR.Get(SRID.CorruptedData));
                }

                ZipIOExtraFieldElement        newElement     = ZipIOExtraFieldElement.Parse(reader, zip64extraFieldUsage);
                ZipIOExtraFieldZip64Element   zip64Element   = newElement as ZipIOExtraFieldZip64Element;
                ZipIOExtraFieldPaddingElement paddingElement = newElement as ZipIOExtraFieldPaddingElement;

                // if we have found the Zip 64 record. let's remember it
                if (zip64Element != null)
                {
                    if (extraField._zip64Element != null)
                    {
                        // multiple ZIP 64 extra fields are not allowed
                        throw new FileFormatException(SR.Get(SRID.CorruptedData));
                    }

                    extraField._zip64Element = zip64Element;
                }
                else if (paddingElement != null)
                {
                    if (extraField._paddingElement != null)
                    {
                        // multiple padding extra fields are not allowed
                        throw new FileFormatException(SR.Get(SRID.CorruptedData));
                    }

                    extraField._paddingElement = paddingElement;
                }
                else
                {
                    if (extraField._extraFieldElements == null)
                    {
                        extraField._extraFieldElements = new ArrayList(3);    // we expect to see a few records there, as it sould have been produced by other authoring systems.
                    }
                    // any other instances of extra fields with the same id are allowed
                    extraField._extraFieldElements.Add(newElement);
                }

                checked { expectedExtraFieldSize -= newElement.Size; }
            }

            // if we didn't end up at the exact expected position, we are treating this as a corrupted file
            if (expectedExtraFieldSize != 0)
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            // As we treat the ZIP 64 extra field as optional for all version >= 4.5
            // we need to explicitly consider a case when it is missing
            if (extraField._zip64Element == null)
            {
                extraField._zip64Element = ZipIOExtraFieldZip64Element.CreateNew();
            }

            /////////////////////////////////////////////////////////////////////
            //              extraField.Validate();
            // an instance Validate function is removed to fix FxCop violation, please add it back
            // if extra validation steps are required
            //
            // we are checking for uniqueness of the Zip 64 header ID in the Parse function.
            // Although it might be a good idea to check for record id uniqueness in general,
            // we are treating the rest of the field as a bag of bits, so it is probably not worth it to
            // search for other duplicate ID especially as appnote considers ID duplication a possibility
            // and even suggest a work around for file producers.
            /////////////////////////////////////////////////////////////////////

            return(extraField);
        }
Exemplo n.º 10
0
        internal static ZipIOExtraField ParseRecord(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage, ushort expectedExtraFieldSize)
        { 
            // most of the files are not ZIP 64, and instead of trying to parse it we should create new empty record
            if (expectedExtraFieldSize == 0)
            {
                if (zip64extraFieldUsage != ZipIOZip64ExtraFieldUsage.None) 
                {
                    // in case there is an expectation by the caller for a non empty record we should throw 
                    throw new FileFormatException(SR.Get(SRID.CorruptedData)); 
                }
 
                // We are creating Extra Fields for the existing Local File Header,
                //  so no need to create a new padding field
                return CreateNew(false);
            } 

            ZipIOExtraField extraField = new ZipIOExtraField(); 
 
            // Parse all Extra elements from Extra Field
            while (expectedExtraFieldSize > 0) 
            {
                if (expectedExtraFieldSize < ZipIOExtraFieldElement.MinimumSize)
                {
                    throw new FileFormatException(SR.Get(SRID.CorruptedData)); 
                }
 
                ZipIOExtraFieldElement newElement = ZipIOExtraFieldElement.Parse(reader, zip64extraFieldUsage); 
                ZipIOExtraFieldZip64Element zip64Element = newElement as ZipIOExtraFieldZip64Element;
                ZipIOExtraFieldPaddingElement paddingElement = newElement as ZipIOExtraFieldPaddingElement; 

                // if we have found the Zip 64 record. let's remember it
                if (zip64Element != null)
                { 
                    if (extraField._zip64Element != null)
                    { 
                        // multiple ZIP 64 extra fields are not allowed 
                        throw new FileFormatException(SR.Get(SRID.CorruptedData));
                    } 

                    extraField._zip64Element = zip64Element;
                }
                else if (paddingElement != null) 
                {
                    if (extraField._paddingElement != null) 
                    { 
                        // multiple padding extra fields are not allowed
                        throw new FileFormatException(SR.Get(SRID.CorruptedData)); 
                    }

                    extraField._paddingElement = paddingElement;
                } 
                else
                { 
                    if (extraField._extraFieldElements == null) 
                        extraField._extraFieldElements = new ArrayList(3);    // we expect to see a few records there, as it sould have been produced by other authoring systems.
 
                    // any other instances of extra fields with the same id are allowed
                    extraField._extraFieldElements.Add(newElement);
                }
 
                checked { expectedExtraFieldSize -= newElement.Size; }
            } 
 
            // if we didn't end up at the exact expected position, we are treating this as a corrupted file
            if (expectedExtraFieldSize != 0) 
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }
 
            // As we treat the ZIP 64 extra field as optional for all version >= 4.5
            // we need to explicitly consider a case when it is missing 
            if (extraField._zip64Element == null) 
            {
                extraField._zip64Element = ZipIOExtraFieldZip64Element.CreateNew(); 
            }

            /////////////////////////////////////////////////////////////////////
            //              extraField.Validate(); 
            // an instance Validate function is removed to fix FxCop violation, please add it back
            // if extra validation steps are required 
            // 
            // we are checking for uniqueness of the Zip 64 header ID in the Parse function.
            // Although it might be a good idea to check for record id uniqueness in general, 
            // we are treating the rest of the field as a bag of bits, so it is probably not worth it to
            // search for other duplicate ID especially as appnote considers ID duplication a possibility
            // and even suggest a work around for file producers.
            ///////////////////////////////////////////////////////////////////// 

            return extraField; 
        }