From 75349ae8c39d01e7e2b5779a18ace750c08e2fd9 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Wed, 9 Jul 2014 11:44:26 -0700 Subject: [PATCH] Fixed incorrect verifier code for nested tables. It was outputting the type instead of the field name, and didn't deal with NULL fields. Added test case. Also fixed token enums having the wrong value, resulting in unreadable error messages. Change-Id: Icd9b4d22f417bfad5824c0f58e067ce3f2e2dc6f Tested: on Windows and Linux. --- include/flatbuffers/flatbuffers.h | 5 +++++ src/idl_gen_cpp.cpp | 8 ++++---- src/idl_parser.cpp | 2 +- tests/MyGame/Example/Monster.java | 5 ++++- tests/monster_test.fbs | 1 + tests/monster_test_generated.h | 13 +++++++++---- tests/monsterdata_test_wire.bin | Bin 176 -> 176 bytes tests/test.cpp | 2 +- 8 files changed, 25 insertions(+), 11 deletions(-) diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index ff3325571..d817e860a 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -582,6 +582,11 @@ class Verifier { return Verify(elem, sizeof(T)); } + // Verify a pointer (may be NULL) of a table type. + template bool VerifyTable(const T *table) const { + return !table || table->Verify(*this); + } + // Verify a pointer (may be NULL) of any vector type. template bool Verify(const Vector *vec) const { const uint8_t *end; diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index bbb8632d0..688ee78d0 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -155,8 +155,8 @@ static void GenComment(const std::string &dc, if (!ev.value) { code_post += ": return true;\n"; // "NONE" enum value. } else { - code_post += ": return reinterpret_castname; - code_post += " *>(union_obj)->Verify(verifier);\n"; + code_post += ": return verifier.VerifyTable(reinterpret_castname + " *>(union_obj));\n"; } } code_post += " default: return false;\n }\n}\n\n"; @@ -213,8 +213,8 @@ static void GenTable(StructDef &struct_def, std::string *code_ptr) { break; case BASE_TYPE_STRUCT: if (!field.value.type.struct_def->fixed) { - code += prefix + field.value.type.struct_def->name; - code += "()->Verify()"; + code += prefix + "verifier.VerifyTable(" + field.name; + code += "())"; } break; case BASE_TYPE_STRING: diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 70f22edfc..e4d2d9421 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -83,7 +83,7 @@ template<> inline Offset atot>(const char *s) { TD(NameSpace, 265, "namespace") \ TD(RootType, 266, "root_type") enum { - #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME, + #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME = VALUE, FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) #undef FLATBUFFERS_TOKEN #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE) kToken ## ENUM, diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java index 26bdf7095..24a3afe53 100755 --- a/tests/MyGame/Example/Monster.java +++ b/tests/MyGame/Example/Monster.java @@ -29,8 +29,10 @@ public class Monster extends Table { public Monster testarrayoftables(int j) { return testarrayoftables(new Monster(), j); } public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; } public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; } + public Monster enemy() { return enemy(new Monster()); } + public Monster enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; } - public static void startMonster(FlatBufferBuilder builder) { builder.startObject(12); } + public static void startMonster(FlatBufferBuilder builder) { builder.startObject(13); } public static void addPos(FlatBufferBuilder builder, int pos) { builder.addStruct(0, pos, 0); } public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); } public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); } @@ -46,6 +48,7 @@ public class Monster extends Table { public static void startTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems); } public static void addTestarrayoftables(FlatBufferBuilder builder, int testarrayoftables) { builder.addOffset(11, testarrayoftables, 0); } public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems); } + public static void addEnemy(FlatBufferBuilder builder, int enemy) { builder.addOffset(12, enemy, 0); } public static int endMonster(FlatBufferBuilder builder) { return builder.endObject(); } }; diff --git a/tests/monster_test.fbs b/tests/monster_test.fbs index a9f95ea20..cf191c410 100755 --- a/tests/monster_test.fbs +++ b/tests/monster_test.fbs @@ -29,6 +29,7 @@ table Monster { /// multiline too testarrayoftables:[Monster] (id: 11); testarrayofstring:[string] (id: 10); + enemy:Monster (id:12); test:Any (id: 8); test4:[Test] (id: 9); } diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index 627cb1fe3..0a45a2086 100755 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -92,6 +92,7 @@ struct Monster : private flatbuffers::Table { const flatbuffers::Vector> *testarrayofstring() const { return GetPointer> *>(24); } /// an example documentation comment: this will end up in the generated code multiline too const flatbuffers::Vector> *testarrayoftables() const { return GetPointer> *>(26); } + const Monster *enemy() const { return GetPointer(28); } bool Verify(const flatbuffers::Verifier &verifier) const { return VerifyTable(verifier) && VerifyField(verifier, 4 /* pos */) && @@ -112,7 +113,9 @@ struct Monster : private flatbuffers::Table { verifier.VerifyVectorOfStrings(testarrayofstring()) && VerifyField(verifier, 26 /* testarrayoftables */) && verifier.Verify(testarrayoftables()) && - verifier.VerifyVectorOfTables(testarrayoftables()); + verifier.VerifyVectorOfTables(testarrayoftables()) && + VerifyField(verifier, 28 /* enemy */) && + verifier.VerifyTable(enemy()); } }; @@ -130,13 +133,15 @@ struct MonsterBuilder { void add_test4(flatbuffers::Offset> test4) { fbb_.AddOffset(22, test4); } void add_testarrayofstring(flatbuffers::Offset>> testarrayofstring) { fbb_.AddOffset(24, testarrayofstring); } void add_testarrayoftables(flatbuffers::Offset>> testarrayoftables) { fbb_.AddOffset(26, testarrayoftables); } + void add_enemy(flatbuffers::Offset enemy) { fbb_.AddOffset(28, enemy); } MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } MonsterBuilder &operator=(const MonsterBuilder &); - flatbuffers::Offset Finish() { return flatbuffers::Offset(fbb_.EndTable(start_, 12)); } + flatbuffers::Offset Finish() { return flatbuffers::Offset(fbb_.EndTable(start_, 13)); } }; -inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos, int16_t mana, int16_t hp, flatbuffers::Offset name, flatbuffers::Offset> inventory, int8_t color, uint8_t test_type, flatbuffers::Offset test, flatbuffers::Offset> test4, flatbuffers::Offset>> testarrayofstring, flatbuffers::Offset>> testarrayoftables) { +inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos, int16_t mana, int16_t hp, flatbuffers::Offset name, flatbuffers::Offset> inventory, int8_t color, uint8_t test_type, flatbuffers::Offset test, flatbuffers::Offset> test4, flatbuffers::Offset>> testarrayofstring, flatbuffers::Offset>> testarrayoftables, flatbuffers::Offset enemy) { MonsterBuilder builder_(_fbb); + builder_.add_enemy(enemy); builder_.add_testarrayoftables(testarrayoftables); builder_.add_testarrayofstring(testarrayofstring); builder_.add_test4(test4); @@ -154,7 +159,7 @@ inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder bool VerifyAny(const flatbuffers::Verifier &verifier, const void *union_obj, uint8_t type) { switch (type) { case Any_NONE: return true; - case Any_Monster: return reinterpret_cast(union_obj)->Verify(verifier); + case Any_Monster: return verifier.VerifyTable(reinterpret_cast(union_obj)); default: return false; } } diff --git a/tests/monsterdata_test_wire.bin b/tests/monsterdata_test_wire.bin index 9a7b16dcc69711559af50124a568a9c77930cb14..f09bf5081d63b77ddffcabf7b9f11d553356e1e9 100755 GIT binary patch literal 176 zcmdO3fB`uM3kD7#hmAo4Na_GFD}w=p2~=7RL^B2ei3WQh;Q&NH3dg>5OXnzFvx*Tl>^%VvI83c+W}O|3X)`GVg~8w1Y+Mx-~7DdlGGv~8vt_> B2;l$# delta 91 zcmdnMxPehqg8>0#7;G3gfLt~P9Uy4{#HIJoG7~k`6+tW?AhrQwkTeSrGXXId Ug9w8hg9d}l#C&N+nTfs106v8WyZ`_I diff --git a/tests/test.cpp b/tests/test.cpp index 901c23032..5aa8157d9 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -91,7 +91,7 @@ std::string CreateFlatBufferTest() { // shortcut for creating monster with all fields set: auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue, Any_Monster, mloc2.Union(), // Store a union. - testv, vecofstrings, vecoftables); + testv, vecofstrings, vecoftables, 0); builder.Finish(mloc);