public bool Validate(string path, out ArchiveValidateError error)
        {
            byte[] buffer = new byte[256 - 4];

            using (var input = File.Open(
                       path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                while (input.Position < input.Length)
                {
                    if (input.Position + 256 > input.Length)
                    {
                        error = new ArchiveValidateError(
                            "end of file for next entry",
                            input);
                        return(false);
                    }

                    input.Read(buffer, 0, buffer.Length);

                    int length = CheckFileName(buffer);
                    if (length < 0)
                    {
                        error = new ArchiveValidateError(
                            "invalid file name",
                            input);
                        return(false);
                    }

                    uint size     = input.ReadValueU32();
                    uint realSize = size.Align(64);

                    if (size == 0 && length == 0)
                    {
                        // this is the last entry
                        if (input.Position == input.Length)
                        {
                            break;
                        }

                        error = new ArchiveValidateError(
                            "null entry not at end of file",
                            input);
                        return(false);
                    }

                    if (input.Position + realSize > input.Length)
                    {
                        error = new ArchiveValidateError(
                            "end of file for data",
                            input);
                        return(false);
                    }

                    input.Seek(realSize, SeekOrigin.Current);
                }

                error = null;
                return(true);
            }
        }
Example #2
0
        public bool Validate(string path, out ArchiveValidateError error)
        {
            using (var input = File.Open(
                       path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                if (input.Length < 8)
                {
                    error = new ArchiveValidateError(
                        "file not large enough to have header",
                        input);
                    return(false);
                }

                var magic = input.ReadValueU32();
                var count = input.ReadValueU32();

                if (magic != 100)
                {
                    error = new ArchiveValidateError(
                        "invalid magic",
                        input);
                    return(false);
                }

                if (input.Length < 8 + (count * 8))
                {
                    error = new ArchiveValidateError(string.Format(
                                                         "file not large enough to support {0} files",
                                                         count), input);
                    return(false);
                }

                long headerSize = 8 + (count * 8);

                for (uint i = 0; i < count; i++)
                {
                    uint offset = input.ReadValueU32();
                    uint size   = input.ReadValueU32();

                    if (offset < headerSize)
                    {
                        error = new ArchiveValidateError(string.Format(
                                                             "entry offset in header",
                                                             count), input);
                        return(false);
                    }

                    if ((long)offset + (long)size > input.Length)
                    {
                        error = new ArchiveValidateError(string.Format(
                                                             "entry exceeds file bounds",
                                                             count), input);
                        return(false);
                    }
                }

                error = null;
                return(true);
            }
        }
Example #3
0
        public bool Validate(string path, out ArchiveValidateError error)
        {
            byte[] buffer = new byte[32];

            using (var input = File.Open(
                       path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                if (input.Length < 4)
                {
                    error = new ArchiveValidateError(
                        "file not large enough to have header",
                        input);
                    return(false);
                }

                var  count   = input.ReadValueU32();
                long atLeast = 4 + (count * (32 + 4));

                if (input.Length < atLeast)
                {
                    error = new ArchiveValidateError(string.Format(
                                                         "file not large enough to support {0} files",
                                                         count), input);
                    return(false);
                }

                for (uint i = 0; i < count; i++)
                {
                    if (input.Position + 36 > input.Length)
                    {
                        error = new ArchiveValidateError(
                            "end of file for next entry",
                            input);
                        return(false);
                    }

                    input.Read(buffer, 0, buffer.Length);

                    int length = CheckFileName(buffer);
                    if (length < 0)
                    {
                        error = new ArchiveValidateError(
                            "invalid file name",
                            input);
                        return(false);
                    }

                    uint size = input.ReadValueU32();

                    if (input.Position + size > input.Length)
                    {
                        error = new ArchiveValidateError(
                            "end of file for data",
                            input);
                        return(false);
                    }

                    input.Seek(size, SeekOrigin.Current);
                }

                if (input.Position != input.Length)
                {
                    error = new ArchiveValidateError(
                        "not at end of file",
                        input);
                    return(false);
                }

                error = null;
                return(true);
            }
        }