Add data validation to Oar entries
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
kayomn 2022-10-11 01:03:02 +01:00
parent 52f4657872
commit e108486c17
2 changed files with 42 additions and 14 deletions

View File

@ -7,8 +7,42 @@ const sys = @import("./sys.zig");
/// Typically, following this block in memory is the file data it holds the meta-information for.
///
pub const Entry = extern struct {
signature: [3]u8,
revision: u8,
name_length: u8,
name_buffer: [255]u8 = std.mem.zeroes([255]u8),
file_size: u64,
padding: [248]u8,
padding: [244]u8,
///
/// Returns `true` if `entry` correctly identifies itself as a valid Oar entry, otherwise
/// `false`.
///
pub fn isValid(entry: Entry) bool {
return std.mem.eql(u8, &entry.signature, "oar");
}
///
/// Attempts to read an [Entry] from `file_access` at its current cursor position.
///
/// Returns the read [Entry] value or `null` if the end of file is reached before completing the
/// read.
///
pub fn read(file_access: *sys.FileAccess) sys.FileAccess.Error!?Entry {
var entry = std.mem.zeroes(Entry);
const origin = try file_access.queryCursor();
if ((try file_access.read(std.mem.asBytes(&entry))) != @sizeOf(Entry)) {
try file_access.seek(origin);
return null;
}
return entry;
}
///
/// Magic identifier used to validate [Entry] data.
///
const signature_magic = "oar";
};

View File

@ -459,22 +459,16 @@ pub const FileSystem = union(enum) {
const file_access = @ptrCast(*FileAccess, ext.SDL_RWFromFile(
&path_buffer, "rb") orelse return error.FileNotFound);
while (true) {
var entry = std.mem.zeroes(oar.Entry);
const entry_buffer = std.mem.asBytes(&entry);
while (oar.Entry.read(file_access) catch return error.FileNotFound) |entry| {
if (!entry.isValid()) break;
if ((file_access.read(entry_buffer) catch return
error.FileNotFound) != entry_buffer.len) return error.FileNotFound;
if (std.mem.eql(u8, entry.name_buffer[0 .. entry.name_length],
path.buffer[0 .. path.length])) return file_access;
if (std.mem.eql(u8, entry.name_buffer[0 .. entry.
name_length], path.buffer[0 .. path.length])) {
return file_access;
file_access.seek(entry.file_size) catch break;
}
file_access.seek(math.roundUp(u64, entry.file_size,
entry_buffer.len)) catch return error.FileNotFound;
}
return error.FileNotFound;
},
.native => |native| {