如何检查 Flatbuffer 是否有效或正确处理错误?

How to check check if a Flatbuffer is valid or handle an error correctly?

我正在使用 Rust 和 Flatbuffers 加载文件。当我尝试加载一个不是有效平面缓冲区文件的文件时,我的程序因索引超出范围而发生混乱。如何向用户显示错误而不崩溃?

小例子:

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

get_root的代码:

#[inline]
pub fn get_root<'a, T: Follow<'a> + 'a>(data: &'a [u8]) -> T::Inner {
    <ForwardsUOffset<T>>::follow(data, 0)
}

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

此实现不进行任何边界检查,将前 4 个字节解释为偏移量,仅在偏移量指向的缓冲区部分调用 follow。我不知道你的上下文中的 T 是什么,但如果文件小于 4 个字节,则此代码将因索引超出范围而出现混乱。如果不是,在 T::follow 的实现中可能会发生类似的情况,因为在我见过的任何 follow 实现中都没有边界检查,而 follow returns 一个裸值,而不是 Result.

这里有两个选择:

  • 向 Flatbuffers 开发人员报告错误,让他们更好地处理损坏的文件。
  • 使用 std::panic::catch_unwind 自行处理恐慌。

免责声明:我在 Google 工作,但我不从事任何与 Flatbuffers 相关的工作。