Ejemplo n.º 1
0
            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;
                }
            }
Ejemplo n.º 2
0
 public EbmlNodeCRC(EbmlSig element, byte[] payload, long start, long count) : base(element)
 {
     this.Start       = start;
     this.Count       = count;
     this.StoredCRC32 = ConvertTo.FromLit32ToUInt32(payload, 0);
 }
Ejemplo n.º 3
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);
            }
Ejemplo n.º 4
0
            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();
            }