【发布时间】:2018-08-20 23:23:29
【问题描述】:
考虑以下 flatbuffers 架构(来自 this stack overflow question):
table Foo {
...
}
table Bar {
value:[Foo];
}
root_type Bar;
假设典型对象中Foos 的数量很大,因此我们希望避免修改架构以使Foo 成为root_type。
场景:
C++ 客户端序列化一个适当的 flatbuffers 对象并将其发布到另一个组件(nodejs 后端),该组件部分反序列化该对象并将表示每个 Foo 的二进制文件作为单独的文档存储在数据库中:
const buf = new flatbuffers.ByteBuffer(req.body)
const bar = fbs.Bar.getRootAsBar(buf)
for (let i = 0; i < bar.valueLength(); i++) {
const foo = bar.value(i)
let item = {
'raw': foo.bb.bytes_ // <-- primary suspect
}
// ... store `item` as an individual entity (mongodb doc)
}
稍后,第三个组件获取存储在 mongodb 文档的“原始”键中的二进制数据,并尝试将其反序列化为 Foo 对象:
auto mongoCol = db.collection("results");
auto mongoResult = mongoCol.find_one(
bsoncxx::builder::stream::document{}
<< "_id" << oid << bsoncxx::builder::stream::finalize);
// ...check that mongoResult is not null
const auto result = mongoResult->view();
const auto& binary = result["raw"].get_binary();
std::string content((const char*)binary.bytes, binary.size);
const auto& foo = flatbuffers::GetRoot<fbs::Foo>(content.c_str());
问题:
但是以foo 给出的指针并不指向预期的数据,并且对foo 的任何操作都可能导致段错误或访问冲突。
怀疑:
我推测根本原因是存储在数据库中的二进制文件根据原始消息使用了偏移量。所以它本身的原始格式基本上是无效的,并且在插入数据库之前应该重新调整偏移量。但是我没有看到任何 flatbuffers 函数 API 来重新调整偏移量?
一个不太可能的根本原因可能是最终的反序列化代码不完整,我们必须重新调整偏移量?
我怀疑它与偏移量有关的原因是,如果我们做出妥协并在每个 Bar 向量中使用一个 Foo 元素发布较小的 flatbuffers 对象(并将后端代码更改为存储 bar.bb.bytes改为raw)。
问题:
无论如何,是否有可能获取您知道代表所需表的较大的正确构造的 flatbuffers 二进制文件的一部分并自行反序列化它?
【问题讨论】:
标签: flatbuffers