/// <summary> /// Test an archive for integrity/validity /// </summary> /// <param name="testData">Perform low level data Crc check</param> /// <returns>true iff the test passes, false otherwise</returns> public bool TestArchive(bool testData) { bool result = true; try { for (int i = 0; i < Size; ++i) { long offset = TestLocalHeader(this[i], true, true); if (testData) { Stream entryStream = this.GetInputStream(this[i]); // TODO: events for updating info, recording errors etc Crc32 crc = new Crc32(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0) { crc.Update(buffer, 0, bytesRead); } if (this[i].Crc != crc.Value) { result = false; // TODO: Event here.... break; // Do all entries giving more info at some point? } } } } catch { result = false; } return result; }
void ReadHeader() { /* 1. Check the two magic bytes */ Crc32 headCRC = new Crc32(); int magic = baseInputStream.ReadByte(); if (magic < 0) { eos = true; return; } headCRC.Update(magic); if (magic != (GZipConstants.GZIP_MAGIC >> 8)) { throw new GZipException("Error baseInputStream GZIP header, first byte doesn't match"); } magic = baseInputStream.ReadByte(); if (magic != (GZipConstants.GZIP_MAGIC & 0xFF)) { throw new GZipException("Error baseInputStream GZIP header, second byte doesn't match"); } headCRC.Update(magic); /* 2. Check the compression type (must be 8) */ int CM = baseInputStream.ReadByte(); if (CM != 8) { throw new GZipException("Error baseInputStream GZIP header, data not baseInputStream deflate format"); } headCRC.Update(CM); /* 3. Check the flags */ int flags = baseInputStream.ReadByte(); if (flags < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } headCRC.Update(flags); /* This flag byte is divided into individual bits as follows: bit 0 FTEXT bit 1 FHCRC bit 2 FEXTRA bit 3 FNAME bit 4 FCOMMENT bit 5 reserved bit 6 reserved bit 7 reserved */ /* 3.1 Check the reserved bits are zero */ if ((flags & 0xd0) != 0) { throw new GZipException("Reserved flag bits baseInputStream GZIP header != 0"); } /* 4.-6. Skip the modification time, extra flags, and OS type */ for (int i=0; i< 6; i++) { int readByte = baseInputStream.ReadByte(); if (readByte < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } headCRC.Update(readByte); } /* 7. Read extra field */ if ((flags & GZipConstants.FEXTRA) != 0) { /* Skip subfield id */ for (int i=0; i< 2; i++) { int readByte = baseInputStream.ReadByte(); if (readByte < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } headCRC.Update(readByte); } if (baseInputStream.ReadByte() < 0 || baseInputStream.ReadByte() < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } int len1, len2, extraLen; len1 = baseInputStream.ReadByte(); len2 = baseInputStream.ReadByte(); if ((len1 < 0) || (len2 < 0)) { throw new GZipException("Early EOF baseInputStream GZIP header"); } headCRC.Update(len1); headCRC.Update(len2); extraLen = (len1 << 8) | len2; for (int i = 0; i < extraLen;i++) { int readByte = baseInputStream.ReadByte(); if (readByte < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } headCRC.Update(readByte); } } /* 8. Read file name */ if ((flags & GZipConstants.FNAME) != 0) { int readByte; while ( (readByte = baseInputStream.ReadByte()) > 0) { headCRC.Update(readByte); } if (readByte < 0) { throw new GZipException("Early EOF baseInputStream GZIP file name"); } headCRC.Update(readByte); } /* 9. Read comment */ if ((flags & GZipConstants.FCOMMENT) != 0) { int readByte; while ( (readByte = baseInputStream.ReadByte()) > 0) { headCRC.Update(readByte); } if (readByte < 0) { throw new GZipException("Early EOF baseInputStream GZIP comment"); } headCRC.Update(readByte); } /* 10. Read header CRC */ if ((flags & GZipConstants.FHCRC) != 0) { int tempByte; int crcval = baseInputStream.ReadByte(); if (crcval < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } tempByte = baseInputStream.ReadByte(); if (tempByte < 0) { throw new GZipException("Early EOF baseInputStream GZIP header"); } crcval = (crcval << 8) | tempByte; if (crcval != ((int) headCRC.Value & 0xffff)) { throw new GZipException("Header CRC value mismatch"); } } readGZIPHeader = true; }