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); } }
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); } }
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); } }