Exemple #1
0
            public Model(Stream stream, byte[] hdr, string path)
            {
                base._data = Data = new FlvFormat(this, stream, path);

                var bb = new byte[15];

                Data.flags = hdr[4];
                if ((Data.flags & 0xA) != 0)
                {
                    IssueModel.Add("Unexpected flags.");
                }
                if ((Data.flags & 5) == 0)
                {
                    IssueModel.Add("Missing audio and video.");
                }

                UInt32 hdrSize = ConvertTo.FromBig32ToUInt32(hdr, 5);

                if (hdrSize != 9)
                {
                    IssueModel.Add("Wrong header size.");
                }

                Data.mediaPosition = 9;
                UInt32 actualPrevSize = 0;

                while (Data.mediaPosition < Data.FileSize)
                {
                    if (Data.mediaPosition + 15 > Data.FileSize)
                    {
                        IssueModel.Add("File truncated near packet header.", Severity.Fatal); return;
                    }

                    Data.fbs.Position = Data.mediaPosition;
                    var got = Data.fbs.Read(bb, 0, bb.Length);
                    if (got < bb.Length)
                    {
                        IssueModel.Add("Read error", Severity.Fatal); return;
                    }

                    Data.mediaPosition += 15;

                    UInt32 storedPrevSize = ConvertTo.FromBig32ToUInt32(bb, 0);
                    if (storedPrevSize != actualPrevSize)
                    {
                        IssueModel.Add("Bad previous packet size.");
                    }

                    byte   packetType = bb[4];
                    UInt32 packetSize = ConvertTo.FromBig24ToUInt32(bb, 5);
                    actualPrevSize = packetSize + 11;

                    ++Data.PacketCount;
                    Data.mediaPosition += packetSize;
                }

                if (Data.mediaPosition > Data.FileSize)
                {
                    IssueModel.Add("File truncated.", Severity.Fatal);
                }
            }
Exemple #2
0
            private void ParseAif(Stream stream, byte[] hdr)
            {
                Data.GroupId  = ConvertTo.FromAsciiToString(hdr, 0, 4);
                Data.FormType = ConvertTo.FromAsciiToString(hdr, 8, 4);

                UInt32 gSize = ConvertTo.FromBig32ToUInt32(hdr, 4);

                if (gSize < 12 || gSize > stream.Length - 8)
                {
                    IssueModel.Add("File truncated or corrupt.", Severity.Fatal); return;
                }

                int    hPos = 12;
                string id0  = ConvertTo.FromAsciiToString(hdr, 12, 4);

                if (Data.IsCompressed)
                {
                    if (id0 != "FVER")
                    {
                        IssueModel.Add("Missing 'FVER' chunk."); return;
                    }

                    UInt32 vSize = ConvertTo.FromBig32ToUInt32(hdr, 16);
                    if (vSize != 4)
                    {
                        IssueModel.Add("Bad 'FVER' chunk."); return;
                    }

                    hPos = 24;
                    id0  = ConvertTo.FromAsciiToString(hdr, 24, 4);
                }

                if (id0 != "COMM")
                {
                    IssueModel.Add("Missing 'COMM' chunk."); return;
                }

                UInt32 cSize = ConvertTo.FromBig32ToUInt32(hdr, hPos + 4);

                if (cSize < 18 || cSize > stream.Length - 8)
                {
                    IssueModel.Add("Bad 'COMM' chunk."); return;
                }

                Data.ChannelCount = ConvertTo.FromBig16ToInt32(hdr, hPos + 8);
                Data.SampleSize   = ConvertTo.FromBig16ToInt32(hdr, hPos + 14);

                ++Data.IffChunkCount;
                Data.IffSize       = gSize;
                Data.mediaPosition = 0;
                Data.MediaCount    = gSize + 8;
                Data.ValidSize     = hPos + cSize + 8;

                var hasSSND = false;
                var buf     = new byte[8];

                while (Data.ValidSize < Data.MediaCount)
                {
                    stream.Position = Data.ValidSize;

                    int got = stream.Read(buf, 0, 8);
                    if (got != 8)
                    {
                        IssueModel.Add("Read failed."); return;
                    }

                    cSize = ConvertTo.FromBig32ToUInt32(buf, 4);
                    if (cSize < 8 || Data.ValidSize + cSize > Data.MediaCount - 8)
                    {
                        IssueModel.Add("Bad chunk size or truncated file."); return;
                    }

                    string id = ConvertTo.FromAsciiToString(buf, 0, 4);
                    if (id == "SSND")
                    {
                        if (hasSSND)
                        {
                            IssueModel.Add("Many 'SSND' chunks."); return;
                        }
                        hasSSND = true;
                    }
                    else if (id != "(c) " && id != "ANNO" && id != "AUTH" && id != "NAME")
                    {
                        IssueModel.Add($"Unexpected '{id}' chunk.", Severity.Trivia, IssueTags.StrictWarn); return;
                    }

                    Data.ValidSize += cSize + 8;
                    if ((cSize & 1) != 0)
                    {
                        ++Data.ValidSize;
                    }
                }

                if (!hasSSND)
                {
                    IssueModel.Add("Missing 'SSND' chunk.", Severity.Warning);
                }
            }
Exemple #3
0
            public Model(Stream stream, string path)
            {
                ChunksModel = new PngChunk.Vector.Model();
                base._data  = Data = new PngFormat(this, stream, path);

                // Arbitrary sanity limit.
                if (Data.FileSize > 100000000)
                {
                    IssueModel.Add("File size insanely huge.", Severity.Fatal);
                    return;
                }

                Data.fBuf = new byte[(int)Data.FileSize];
                var fBuf = Data.fBuf;

                stream.Position = 0;
                int got = stream.Read(fBuf, 0, (int)Data.FileSize);

                if (got < Data.FileSize)
                {
                    IssueModel.Add("Read failed.", Severity.Fatal);
                    return;
                }

                Data.ValidSize = 8;
                do
                {
                    UInt32 chunkSize = ConvertTo.FromBig32ToUInt32(fBuf, (int)Data.ValidSize);
                    if (Data.ValidSize + chunkSize + 12 > Data.FileSize)
                    {
                        IssueModel.Add("File is corrupt or truncated.", Severity.Fatal);
                        return;
                    }

                    string type      = Encoding.ASCII.GetString(fBuf, (int)Data.ValidSize + 4, 4);
                    UInt32 storedCRC = ConvertTo.FromBig32ToUInt32(fBuf, (int)(Data.ValidSize + chunkSize + 8));
                    ChunksModel.Add(type, chunkSize, storedCRC);

                    var typeLow = type.ToLower();
                    switch (typeLow)
                    {
                    case "idat":
                        if (Data.mediaPosition <= 0)
                        {
                            Data.mediaPosition = Data.ValidSize;
                        }
                        break;

                    case "iend":
                        if (Data.MediaCount > 0)
                        {
                            IssueModel.Add("Multiple IEND chunks.");
                        }
                        else
                        {
                            Data.MediaCount = Data.ValidSize - Data.mediaPosition + chunkSize + 0xC;
                        }
                        break;

                    case "ihdr":
                        if (chunkSize < 13)
                        {
                            IssueModel.Add("IHDR chunk is short.");
                        }
                        else if (Data.Width != null)
                        {
                            IssueModel.Add("Multiple IHDR chunks.");
                        }
                        else
                        {
                            Data.Width             = ConvertTo.FromBig32ToInt32(fBuf, (int)Data.ValidSize + 8);
                            Data.Height            = ConvertTo.FromBig32ToInt32(fBuf, (int)Data.ValidSize + 12);
                            Data.BitDepth          = fBuf[(int)Data.ValidSize + 16];
                            Data.ColorType         = fBuf[(int)Data.ValidSize + 17];
                            Data.CompressionMethod = fBuf[(int)Data.ValidSize + 18];
                            Data.FilterMethod      = fBuf[(int)Data.ValidSize + 19];
                            Data.InterlaceMethod   = fBuf[(int)Data.ValidSize + 20];
                        }
                        break;

                    case "phys":
                        if (chunkSize < 9)
                        {
                            IssueModel.Add("PHYS chunk is short.");
                        }
                        else if (Data.DotsPerMeter1 != null)
                        {
                            IssueModel.Add("Multiple PHYS chunks.");
                        }
                        else
                        {
                            Data.DotsPerMeter1 = ConvertTo.FromBig32ToInt32(fBuf, (int)Data.ValidSize + 8);
                            Data.DotsPerMeter2 = ConvertTo.FromBig32ToInt32(fBuf, (int)Data.ValidSize + 12);
                            Data.Units         = fBuf[(int)Data.ValidSize + 9];
                        }
                        break;

                    case "text":
                        if (chunkSize > 0x7FFF)
                        {
                            IssueModel.Add("String size too large.");
                        }
                        else
                        {
                            var escaped = new StringBuilder();
                            for (int ix = (int)Data.ValidSize + 8; ix < (int)Data.ValidSize + 8 + chunkSize; ++ix)
                            {
                                if (fBuf[ix] < ' ' || fBuf[ix] > 0x7F)
                                {
                                    escaped.Append($"\\{fBuf[ix]:x2}");
                                }
                                else
                                {
                                    escaped.Append((char)fBuf[ix]);
                                }
                            }

                            Data.texts.Add(escaped.ToString());
                        }
                        break;

                    case "gama":
                        if (chunkSize < 4)
                        {
                            IssueModel.Add("GAMA chunk is short.");
                        }
                        else if (Data.Gamma != null)
                        {
                            IssueModel.Add("Multiple GAMA chunks.");
                        }
                        else
                        {
                            Data.Gamma = ConvertTo.FromBig32ToUInt32(fBuf, (int)Data.ValidSize + 8) / 100000f;
                        }
                        break;
                    }

                    Data.ValidSize += chunkSize + 0xC;
                }while (Data.ValidSize < Data.FileSize);

                if (Data.Width == null)
                {
                    IssueModel.Add("Missing IHDR chunk.");
                }

                if (Data.Chunks.Items[Data.Chunks.Items.Count - 1].Type != "IEND")
                {
                    IssueModel.Add("Missing IEND chunk.");
                }

                if (Data.Width <= 0 || Data.Height <= 0)
                {
                    IssueModel.Add("Invalid dimensions.");
                }

                if (Data.DotsPerMeter1 != Data.DotsPerMeter2)
                {
                    IssueModel.Add("Density aspect not 1.", Severity.Warning);
                }

                if (Data.BitDepth != 1 && Data.BitDepth != 2 && Data.BitDepth != 4 && Data.BitDepth != 8 && Data.BitDepth != 16)
                {
                    IssueModel.Add($"Invalid bit depth '{Data.BitDepth}'.");
                }

                if (Data.CompressionMethod != 0)
                {
                    IssueModel.Add($"Invalid compression '{Data.CompressionMethod}'.");
                }

                if (Data.FilterMethod != 0)
                {
                    IssueModel.Add($"Invalid filter '{Data.FilterMethod}'.");
                }

                if (Data.InterlaceMethod != 0 && Data.InterlaceMethod != 1)
                {
                    IssueModel.Add($"Invalid interlace '{Data.InterlaceMethod}'.");
                }
            }