protected void ParseRiff(byte[] hdr) { var buf = new byte[8]; long chunkSize = ConvertTo.FromLit32ToUInt32(hdr, 4) + 8; if (chunkSize % 1 != 0) { IssueModel.Add("RIFF has odd sized chunk, some tools don't pad this correctly", Severity.Trivia); } do { if (Data.ValidSize + chunkSize > Data.FileSize) { IssueModel.Add("File truncated", Severity.Fatal); return; } ++Data.IffChunkCount; Data.IffSize = Data.ValidSize = Data.ValidSize + chunkSize; if (Data.ValidSize + 8 > Data.FileSize) { // Not enough bytes for a header. return; } try { Data.fbs.Position = Data.ValidSize; } catch (EndOfStreamException) { IssueModel.Add("File truncated or corrupt.", Severity.Fatal); return; } var got = Data.fbs.Read(buf, 0, 8); if (got != 8) { IssueModel.Add("Read error", Severity.Fatal); return; } chunkSize = ConvertTo.FromLit32ToUInt32(buf, 4) + 8; }while (buf[0] == 'R' || buf[1] == 'I' || buf[2] == 'F' || buf[3] == 'F'); if (buf[0] == 'J' && buf[1] == 'U' && buf[2] == 'N' && buf[3] == 'K') { if (Data.ValidSize + chunkSize > Data.FileSize) { IssueModel.Add("File corrupt or truncated", Severity.Fatal); return; } Data.JunkSize = chunkSize; Data.ValidSize += Data.JunkSize; } }
public EbmlNodeCRC(EbmlSig element, byte[] payload, long start, long count) : base(element) { this.Start = start; this.Count = count; this.StoredCRC32 = ConvertTo.FromLit32ToUInt32(payload, 0); }
public override void CalcHashes(Hashes hashFlags, Validations validationFlags) { if (Data.Issues.HasFatal) { return; } if ((hashFlags & Hashes.Intrinsic) != 0) { var buf1 = new byte[27 + 256]; byte[] buf2 = null; Data.PageCount = 0; while (Data.ValidSize < Data.FileSize) { Data.fbs.Position = Data.ValidSize; ++Data.PageCount; var got = Data.fbs.Read(buf1, 0, buf1.Length); if (got < buf1.Length) { IssueModel.Add("Read failed near header", Severity.Fatal); return; } int segmentCount = buf1[26]; UInt32 storedHeaderCRC32 = ConvertTo.FromLit32ToUInt32(buf1, 22); int pageSize = 27 + segmentCount; for (int ix = 27; ix < 27 + segmentCount; ++ix) { pageSize += buf1[ix]; } Data.fbs.Position = Data.ValidSize; if (buf2 == null || buf2.Length < pageSize) { buf2 = new byte[pageSize]; } got = Data.fbs.Read(buf2, 0, pageSize); if (got < pageSize) { IssueModel.Add("Read failed near page " + Data.PageCount, Severity.Fatal); return; } buf2[22] = 0; buf2[23] = 0; buf2[24] = 0; buf2[25] = 0; UInt32 actualHeaderCRC32; var hasher = new Crc32n0Hasher(); hasher.Append(buf2, 0, pageSize); var hash = hasher.GetHashAndReset(); actualHeaderCRC32 = BitConverter.ToUInt32(hash, 0); if (actualHeaderCRC32 != storedHeaderCRC32) { Data.badPage.Add(Data.PageCount.Value); } Data.ValidSize += pageSize; } if (Data.badPage.Count == 0) { Data.CdIssue = IssueModel.Add($"CRC-32 checks successful on {Data.PageCount} pages.", Severity.Advisory, IssueTags.Success); } else { var err = $"CRC-32 checks failed on {Data.badPage.Count} of {Data.PageCount} pages."; Data.CdIssue = IssueModel.Add(err, Severity.Error, IssueTags.Failure); } } base.CalcHashes(hashFlags, validationFlags); }
public Model(Stream stream, byte[] hdr, string path) { base._data = Data = new WavFormat(this, stream, path); ParseRiff(hdr); Data.ActualCRC32 = null; if (Data.Issues.HasFatal) { return; } if (hdr.Length < 0x2C) { IssueModel.Add("File truncated near header", Severity.Fatal); return; } if (Data.IffChunkCount > 1) { IssueModel.Add("Contains multiple RIFF chunks", Severity.Fatal); return; } int hPos = 0x0C; if (hdr[hPos] != 'f' || hdr[hPos + 1] != 'm' || hdr[hPos + 2] != 't' || hdr[hPos + 3] != 0x20) { IssueModel.Add("Missing 'fmt' section", Severity.Fatal); return; } Data.CompCode = hdr[hPos + 8] | hdr[hPos + 9] << 8; Data.ChannelCount = hdr[hPos + 0x0A] | hdr[hPos + 0x0B] << 8; Data.SampleRate = ConvertTo.FromLit32ToUInt32(hdr, hPos + 0x0C); Data.AverageBPS = ConvertTo.FromLit32ToUInt32(hdr, hPos + 0x10); Data.BlockAlign = hdr[hPos + 0x14] | hdr[hPos + 0x15] << 8; Data.BitsPerSample = hdr[hPos + 0x16] | hdr[hPos + 0x17] << 8; if ((hdr[hPos] & 0x80) != 0) { IssueModel.Add("Header size insanely huge", Severity.Fatal); return; } long hdrDataSize = ConvertTo.FromLit32ToInt32(hdr, hPos + 4); long dataPos = hPos + 8 + hdrDataSize; stream.Position = dataPos; var dHdr = new byte[8]; if (stream.Read(dHdr, 0, 8) != 8) { IssueModel.Add("Read failed", Severity.Fatal); return; } if (dHdr[0] != 'd' || dHdr[1] != 'a' || dHdr[2] != 't' || dHdr[3] != 'a') { IssueModel.Add("Missing 'data' section", Severity.Fatal); return; } Data.mediaPosition = dataPos + 8; Data.MediaCount = ConvertTo.FromLit32ToUInt32(dHdr, 4); if (Data.mediaPosition + Data.MediaCount > Data.IffSize) { IssueModel.Add("Invalid data size", Severity.Fatal); return; } Data.HasTags = Data.mediaPosition + Data.MediaCount < Data.IffSize; GetDiagnostics(); }