我正在使用Rust和Flatbuffers加载文件。当我尝试加载不是有效的Flatbuffer文件的文件时,我的程序出现了索引超出范围的错误消息。如何向用户显示错误而不崩溃?

小例子:

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返回的是裸值,而不是Result

您在这里有两个选择:
  • 向Flatbuffers开发人员报告错误,并让他们更好地处理损坏的文件。
  • 使用 std::panic::catch_unwind 自己处理 panic 。

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

    10-08 17:24