private void SkipAttribute(DataReader mReader) { ulong size = mReader.ReadPackedUInt64(); if(size > (ulong)mReader.Remaining) throw new InvalidDataException(); mReader.Skip((long)size); }
private void ReadHeader(DataReader mReader) { byte[] signature = mReader.ReadBytes(kSignature.Length); if(signature.Length != kSignature.Length) throw new InvalidDataException(); for(int i = 0; i < signature.Length; i++) if(signature[i] != kSignature[i]) throw new InvalidDataException(); mMajorVersion = mReader.ReadByte(); mMinorVersion = mReader.ReadByte(); if(mMajorVersion != 0) throw new NotSupportedException(); // TODO: Weak check of supported minor versions uint startHeaderCRC = mReader.ReadUInt32(); long nextHeaderOffset = mReader.ReadInt64(); long nextHeaderLength = mReader.ReadInt64(); uint nextHeaderCRC = mReader.ReadUInt32(); Utils.Assert(mReader.Position == kPrimaryHeaderSize); if(mCheckCRC) { uint crc = CRC.kInitCRC; crc = CRC.Update(crc, nextHeaderOffset); crc = CRC.Update(crc, nextHeaderLength); crc = CRC.Update(crc, nextHeaderCRC); crc = CRC.Finish(crc); if(crc != startHeaderCRC) throw new InvalidDataException(); } if(nextHeaderLength < 0 || nextHeaderOffset < 0 || nextHeaderOffset > mReader.Remaining - nextHeaderLength) throw new InvalidDataException(); if(nextHeaderLength > 0) // zero is ok, empty archive { mReader.Skip(nextHeaderOffset); if(mCheckCRC) { if(mReader.CalculateCRC(nextHeaderLength) != nextHeaderCRC) throw new InvalidDataException(); mReader.Seek(kPrimaryHeaderSize + nextHeaderOffset); } using(mReader.Constrain(nextHeaderLength)) ReadHeader2(mReader); } }