1

私はこれをあまりにも長い間見つめてきましたが、それは私が間違っていることだと確信しています. テーブル メンバーを追加しようとした後、フラットバッファが検証に失敗します。構造体の先頭に整数のみを追加すると、正常に検証されます。

ルート スキーマ:

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

問題のあることの 1 つは、所有GetBufferPointerする内部バッファーへのポインターを提供し、そのバッファーを所有するスマート ポインターを作成してから削除することです。fbbReleaseBufferPointerfbb

スマート ポインターを保存することさえしていないので、おそらくまったく呼び出したくないでしょうReleaseBufferPointer

ただし、ほとんどの場合、元のポインターbufは引き続き有効であるため、それが検証エラーの原因であるかどうかはわかりません。ルート テーブルの vtable オフセットの読み取りに失敗します。これは、バッファ全体が偽物であることを示しています。

于 2016-09-30T02:00:20.437 に答える