1

我已经盯着这个太久了,我确定这是我做错了。尝试添加表成员后,我的 flatbuffer 无法验证。如果我只在结构的顶部添加整数,它会很好地验证。

根架构:

table TestRootForBasicTypeTables
{
    test_int_value:int;
    test_ubyte:ubyte_table;
    …

上述模式的“C”结构定义

struct TestRootForBasicTypeTables
{
    int test_int_value;

    ////
    //// Structures for unary types
    ////
    ubyte_table test_ubyte;
    byte_table test_byte;
    …

ubyte_table 的架构:

table ubyte_table
{
    ubyte_value:ubyte;
}

ubyte_table的结构体定义

struct ubyte_table
{
    UCHAR ubyte_value;
};

仅添加 test_int_value 时的字节缓冲区:

48 0 0 0 
44 0 
8 0 <= size of data
4 0 <= offset from root to integer value
0 0 <= all other offsets are zero
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
44 0 0 0 <= root table
41 0 0 0 <= integer value

添加 ubyte_table 时的字节缓冲区

48 0 0 0 
44 0 
14 0 <= size of data
4 0 <= offset from root to integer value
8 0 <= offset from root to test_ubyte
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
44 0 0 0 
41 0 0 0 <= integer value
12 0 <= length of test_ubyte data
0 0 
0 0 
6 0 
8 0 
7 0 
6 0 
0 0 0 0 0 55

这是代码:

flatbuffers::Offset< FBS_NS::TestRootForSonusBasicTypeTables> writeFlatbuffers(flatbuffers::FlatBufferBuilder &fbb)
{
    return FBS_NS::CreateTestRootForBasicTypeTables(fbb,
                       41,
                      SONUS_FBS_NS::Createubyte_table(fbb, 55));
}

void BasicTypeTablesUnitTest::testHelper_(void)
{
    flatbuffers::FlatBufferBuilder  fbb;

    // Set test value and serialize data
    FBS_NS::FinishTestRootForBasicTypeTablesBuffer(fbb, ::writeFlatbuffers(fbb, input));

    #if (DBG_PRT==1)
    // print byte data for debugging:
    auto p = fbb.GetBufferPointer();
    for (flatbuffers::uoffset_t i = 0; i < fbb.GetSize(); i++)
        printf("%d ", p[i]);
    printf("\n");
    #endif /* DBG_PRT */

    auto *buf = fbb.GetBufferPointer();
    auto size = fbb.GetSize();
    fbb.ReleaseBufferPointer();

    flatbuffers::Verifier verifier(buf, size);
        CPPUNIT_ASSERT(FBS_NS::VerifyTestRootForBasicTypeTablesBuffer(verifier));

    // deserialize data into the output structure
    const FBS_NS::TestRootForBasicTypeTables *root = FBS_NS::GetTestRootForBasicTypeTables((const void*)buf);
  ::readFlatbuffers(root, output);
}

验证失败的堆栈跟踪

(gdb) where
#0  0x00007ffff6ed7125 in raise () from /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/kernel/3.2/debug/lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff6eda3a0 in abort () from /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/kernel/3.2/debug/lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff6ed0311 in __assert_fail () from /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/kernel/3.2/debug/lib/x86_64-linux-gnu/libc.so.6
#3  0x000000000043428e in flatbuffers::Verifier::Check (this=0x7fffffffca50, ok=false) at /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/flatbuffers/include/flatbuffers/flatbuffers.h:942
#4  0x0000000000434308 in flatbuffers::Verifier::Verify (this=0x7fffffffca50, elem=0x6967f3, elem_len=4) at /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/flatbuffers/include/flatbuffers/flatbuffers.h:949
#5  0x0000000000437f8c in flatbuffers::Verifier::Verify<int> (this=0x7fffffffca50, elem=0x6967f3) at /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/flatbuffers/include/flatbuffers/flatbuffers.h:954
#6  0x0000000000434451 in flatbuffers::Table::VerifyTableStart (this=0x6967f3, verifier=...) at /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/flatbuffers/include/flatbuffers/flatbuffers.h:1146
#7  0x0000000000434e9b in FBS_NS::TestRootForBasicTypeTables::Verify (this=0x6967f3, verifier=...) at TestRootForBasicTypeTables_generated.h:71
#8  0x0000000000439410 in flatbuffers::Verifier::VerifyBuffer< FBS_NS::TestRootForBasicTypeTables> (this=0x7fffffffca50) at /sonus/p4/ws/dmccracken/dsbc_cmnthirdparty/flatbuffers/include/flatbuffers/flatbuffers.h:1020
#9  0x0000000000435acb in FBS_NS::VerifyTestRootForBasicTypeTablesBuffer (verifier=...) at TestRootForSonusBasicTypeTables_generated.h:202
#10 0x000000000042d97b in BasicTypeTablesUnitTest::testHelper_ (this=0x66ec80) at BasicTypeTablesUnitTest.cpp:324
#11 0x000000000042db25 in BasicTypeTablesUnitTest::test_ubyte (this=0x66ec80) at BasicTypeTablesUnitTest.cpp:349
4

1 回答 1

0

有问题的一件事是,它GetBufferPointer为您提供了一个指向拥有的内部缓冲区的指针fbb,然后ReleaseBufferPointer创建一个拥有该缓冲区的智能指针,并将其从fbb.

由于您甚至不存储智能指针,我猜您可能根本不想打电话ReleaseBufferPointer

但是,在大多数情况下,原始指针buf仍然有效,所以我不知道这是否是验证器失败的原因。它无法读取根表的 vtable 偏移量,这表明整个缓冲区是伪造的。

于 2016-09-30T02:00:20.437 回答