Commit ca417426 authored by Frank Benkstein's avatar Frank Benkstein Committed by Wouter van Oortmerssen

make flatbuffers::IsFieldPresent safer (#4988)

Give the vtable offset enum inside each table the name
"FlatBuffersVTableOffset" and base type voffset_t so it can be used as a
dependent type in IsFieldPresent. This makes that function slightly
safer since it prevents calling it with arbitrary, non-table types.
Now, the only way to use IsFieldPresent incorrectly is to create your
own type which does not inherit from flatbuffers::Table but has a
dependent voffset convertible type "FlatBuffersVTableOffset".
parent 55b30827
......@@ -122,9 +122,11 @@
defined(__clang__)
#define FLATBUFFERS_FINAL_CLASS final
#define FLATBUFFERS_OVERRIDE override
#define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t
#else
#define FLATBUFFERS_FINAL_CLASS
#define FLATBUFFERS_OVERRIDE
#define FLATBUFFERS_VTABLE_UNDERLYING_TYPE
#endif
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
......
......@@ -2370,9 +2370,11 @@ typedef uint64_t hash_value_t;
// Note: this function will return false for fields equal to the default
// value, since they're not stored in the buffer (unless force_defaults was
// used).
template<typename T> bool IsFieldPresent(const T *table, voffset_t field) {
template<typename T>
bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) {
// Cast, since Table is a private baseclass of any table types.
return reinterpret_cast<const Table *>(table)->CheckField(field);
return reinterpret_cast<const Table *>(table)->CheckField(
static_cast<voffset_t>(field));
}
// Utility function for reverse lookups on the EnumNames*() functions
......
......@@ -100,7 +100,7 @@ inline const char *EnumNameBaseType(BaseType e) {
}
struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_BASE_TYPE = 4,
VT_ELEMENT = 6,
VT_INDEX = 8
......@@ -160,7 +160,7 @@ inline flatbuffers::Offset<Type> CreateType(
}
struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_KEY = 4,
VT_VALUE = 6
};
......@@ -229,7 +229,7 @@ inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
}
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_VALUE = 6,
VT_OBJECT = 8,
......@@ -337,7 +337,7 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
}
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_VALUES = 6,
VT_IS_UNION = 8,
......@@ -462,7 +462,7 @@ inline flatbuffers::Offset<Enum> CreateEnumDirect(
}
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_TYPE = 6,
VT_ID = 8,
......@@ -644,7 +644,7 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
}
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_FIELDS = 6,
VT_IS_STRUCT = 8,
......@@ -779,7 +779,7 @@ inline flatbuffers::Offset<Object> CreateObjectDirect(
}
struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_REQUEST = 6,
VT_RESPONSE = 8,
......@@ -891,7 +891,7 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
}
struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_CALLS = 6,
VT_ATTRIBUTES = 8,
......@@ -989,7 +989,7 @@ inline flatbuffers::Offset<Service> CreateServiceDirect(
}
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_OBJECTS = 4,
VT_ENUMS = 6,
VT_FILE_IDENT = 8,
......
......@@ -235,7 +235,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_POS = 4,
VT_MANA = 6,
VT_HP = 8,
......@@ -443,7 +443,7 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return WeaponTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_DAMAGE = 6
};
......
......@@ -1710,7 +1710,7 @@ class CppGenerator : public BaseGenerator {
// We need to add a trailing comma to all elements except the last one as
// older versions of gcc complain about this.
code_.SetValue("SEP", "");
code_ += " enum {";
code_ += " enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
......
......@@ -539,7 +539,7 @@ struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TestSimpleTableWithEnumTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_COLOR = 4
};
Color color() const {
......@@ -609,7 +609,7 @@ struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return StatTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_ID = 4,
VT_VAL = 6,
VT_COUNT = 8
......@@ -713,7 +713,7 @@ struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return ReferrableTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_ID = 4
};
uint64_t id() const {
......@@ -882,7 +882,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_POS = 4,
VT_MANA = 6,
VT_HP = 8,
......@@ -1665,7 +1665,7 @@ struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TypeAliasesTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_I8 = 4,
VT_U8 = 6,
VT_I16 = 8,
......
......@@ -82,7 +82,7 @@ struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TableInNestedNSTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_FOO = 4
};
int32_t foo() const {
......
......@@ -42,7 +42,7 @@ struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TableInFirstNSTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_FOO_TABLE = 4,
VT_FOO_ENUM = 6,
VT_FOO_STRUCT = 8
......@@ -119,7 +119,7 @@ struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TableInCTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_REFER_TO_A1 = 4,
VT_REFER_TO_A2 = 6
};
......@@ -184,7 +184,7 @@ struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return SecondTableInATypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_REFER_TO_C = 4
};
const NamespaceC::TableInC *refer_to_c() const {
......
......@@ -251,7 +251,7 @@ struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return AttackerTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_SWORD_ATTACK_DAMAGE = 4
};
int32_t sword_attack_damage() const {
......@@ -317,7 +317,7 @@ struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MovieTypeTable();
}
enum {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_MAIN_CHARACTER_TYPE = 4,
VT_MAIN_CHARACTER = 6,
VT_CHARACTERS_TYPE = 8,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment