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

don't crash when calling EnumNameXXX on sparse enum (#4982)

Make an out-of-bounds check for enum values before using them to index the
names array.  For consistency with non-sparse enums an empty string is
returned.

Fixes #4821
parent a4f9d1bf
...@@ -55,6 +55,7 @@ inline const char * const *EnumNamesColor() { ...@@ -55,6 +55,7 @@ inline const char * const *EnumNamesColor() {
} }
inline const char *EnumNameColor(Color e) { inline const char *EnumNameColor(Color e) {
if (e < Color_Red || e > Color_Blue) return "";
const size_t index = static_cast<int>(e); const size_t index = static_cast<int>(e);
return EnumNamesColor()[index]; return EnumNamesColor()[index];
} }
...@@ -84,6 +85,7 @@ inline const char * const *EnumNamesEquipment() { ...@@ -84,6 +85,7 @@ inline const char * const *EnumNamesEquipment() {
} }
inline const char *EnumNameEquipment(Equipment e) { inline const char *EnumNameEquipment(Equipment e) {
if (e < Equipment_NONE || e > Equipment_Weapon) return "";
const size_t index = static_cast<int>(e); const size_t index = static_cast<int>(e);
return EnumNamesEquipment()[index]; return EnumNamesEquipment()[index];
} }
......
...@@ -991,6 +991,10 @@ class CppGenerator : public BaseGenerator { ...@@ -991,6 +991,10 @@ class CppGenerator : public BaseGenerator {
code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {"; code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {";
code_ += " if (e < " + GetEnumValUse(enum_def, *enum_def.vals.vec.front()) +
" || e > " + GetEnumValUse(enum_def, *enum_def.vals.vec.back()) +
") return \"\";";
code_ += " const size_t index = static_cast<int>(e)\\"; code_ += " const size_t index = static_cast<int>(e)\\";
if (enum_def.vals.vec.front()->value) { if (enum_def.vals.vec.front()->value) {
auto vals = GetEnumValUse(enum_def, *enum_def.vals.vec.front()); auto vals = GetEnumValUse(enum_def, *enum_def.vals.vec.front());
......
...@@ -122,6 +122,7 @@ inline const char * const *EnumNamesColor() { ...@@ -122,6 +122,7 @@ inline const char * const *EnumNamesColor() {
} }
inline const char *EnumNameColor(Color e) { inline const char *EnumNameColor(Color e) {
if (e < Color_Red || e > Color_Blue) return "";
const size_t index = static_cast<int>(e) - static_cast<int>(Color_Red); const size_t index = static_cast<int>(e) - static_cast<int>(Color_Red);
return EnumNamesColor()[index]; return EnumNamesColor()[index];
} }
...@@ -157,6 +158,7 @@ inline const char * const *EnumNamesAny() { ...@@ -157,6 +158,7 @@ inline const char * const *EnumNamesAny() {
} }
inline const char *EnumNameAny(Any e) { inline const char *EnumNameAny(Any e) {
if (e < Any_NONE || e > Any_MyGame_Example2_Monster) return "";
const size_t index = static_cast<int>(e); const size_t index = static_cast<int>(e);
return EnumNamesAny()[index]; return EnumNamesAny()[index];
} }
......
...@@ -45,6 +45,7 @@ inline const char * const *EnumNamesEnumInNestedNS() { ...@@ -45,6 +45,7 @@ inline const char * const *EnumNamesEnumInNestedNS() {
} }
inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) { inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) {
if (e < EnumInNestedNS_A || e > EnumInNestedNS_C) return "";
const size_t index = static_cast<int>(e); const size_t index = static_cast<int>(e);
return EnumNamesEnumInNestedNS()[index]; return EnumNamesEnumInNestedNS()[index];
} }
......
...@@ -1285,6 +1285,14 @@ void EnumStringsTest() { ...@@ -1285,6 +1285,14 @@ void EnumStringsTest() {
true); true);
} }
void EnumNamesTest() {
TEST_EQ_STR("Red", EnumNameColor(Color_Red));
TEST_EQ_STR("Green", EnumNameColor(Color_Green));
TEST_EQ_STR("Blue", EnumNameColor(Color_Blue));
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(-1)));
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(1000)));
}
void IntegerOutOfRangeTest() { void IntegerOutOfRangeTest() {
TestError("table T { F:byte; } root_type T; { F:128 }", TestError("table T { F:byte; } root_type T; { F:128 }",
"constant does not fit"); "constant does not fit");
...@@ -2058,6 +2066,7 @@ int FlatBufferTests() { ...@@ -2058,6 +2066,7 @@ int FlatBufferTests() {
ErrorTest(); ErrorTest();
ValueTest(); ValueTest();
EnumStringsTest(); EnumStringsTest();
EnumNamesTest();
IntegerOutOfRangeTest(); IntegerOutOfRangeTest();
IntegerBoundaryTest(); IntegerBoundaryTest();
UnicodeTest(); UnicodeTest();
......
...@@ -69,6 +69,7 @@ inline const char * const *EnumNamesCharacter() { ...@@ -69,6 +69,7 @@ inline const char * const *EnumNamesCharacter() {
} }
inline const char *EnumNameCharacter(Character e) { inline const char *EnumNameCharacter(Character e) {
if (e < Character_NONE || e > Character_Unused) return "";
const size_t index = static_cast<int>(e); const size_t index = static_cast<int>(e);
return EnumNamesCharacter()[index]; return EnumNamesCharacter()[index];
} }
......
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