I‘m using Rust and Flatbuffers to load files. When I try to load a file which is not a valid flatbuffer file, my program panics with an index out of range. How can I show a error to the user and not crash?
Small Example:
file_content_as_u8 // This is my &[u8] where I have loaded the file content.
// &[u8] to fltabuffer where get_root_as_file is generated by flatbuffer
let file_content = get_root_as_file(file_content_as_u8);
// Try to read data field from flatbuffer
let data = file_content.data();
// If file_content_as_u8 wasn't a valid flatbuffer file file_content.data()
// results in a panic with an index out of range
The code for get_root
:
#[inline]
pub fn get_root<'a, T: Follow<'a> + 'a>(data: &'a [u8]) -> T::Inner {
<ForwardsUOffset<T>>::follow(data, 0)
}
The implementation for Follow
for ForwardsUOffset
:
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
type Inner = T::Inner;
#[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_UOFFSET];
let off = read_scalar::<u32>(slice) as usize;
T::follow(buf, loc + off)
}
}
This implementation does not do any bounds checking, interprets the first 4 bytes as an offset, and just calls follow
on the part of the buffer pointed to by offset. I don't know what T
is in your context, but if the file is smaller than 4 bytes, this code will panic with an index out of range. If it is not, a similar situation can happen in the implementation of T::follow
, since there's no bounds checking in any of the follow
implementations that I've seen, and follow
returns a naked value, not Result
.
You have two options here:
std::panic::catch_unwind
.Disclaimer: I work at Google, but I don't work on anything related to Flatbuffers.