mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-28 06:08:06 +00:00
Fix confrom failure for nullptr dereference. (#7688)
This commit is contained in:
@@ -541,8 +541,11 @@ inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
|
|||||||
inline bool EqualByName(const Type &a, const Type &b) {
|
inline bool EqualByName(const Type &a, const Type &b) {
|
||||||
return a.base_type == b.base_type && a.element == b.element &&
|
return a.base_type == b.base_type && a.element == b.element &&
|
||||||
(a.struct_def == b.struct_def ||
|
(a.struct_def == b.struct_def ||
|
||||||
a.struct_def->name == b.struct_def->name) &&
|
(a.struct_def != nullptr && b.struct_def != nullptr &&
|
||||||
(a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name);
|
a.struct_def->name == b.struct_def->name)) &&
|
||||||
|
(a.enum_def == b.enum_def ||
|
||||||
|
(a.enum_def != nullptr && b.enum_def != nullptr &&
|
||||||
|
a.enum_def->name == b.enum_def->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RPCCall : public Definition {
|
struct RPCCall : public Definition {
|
||||||
|
|||||||
@@ -4239,8 +4239,13 @@ std::string Parser::ConformTo(const Parser &base) {
|
|||||||
field_base = *fbit;
|
field_base = *fbit;
|
||||||
if (field.value.offset == field_base->value.offset) {
|
if (field.value.offset == field_base->value.offset) {
|
||||||
renamed_fields.insert(field_base);
|
renamed_fields.insert(field_base);
|
||||||
if (!EqualByName(field.value.type, field_base->value.type))
|
if (!EqualByName(field.value.type, field_base->value.type)) {
|
||||||
return "field renamed to different type: " + qualified_field_name;
|
const auto qualified_field_base =
|
||||||
|
qualified_name + "." + field_base->name;
|
||||||
|
return "field renamed to different type: " +
|
||||||
|
qualified_field_name + " (renamed from " +
|
||||||
|
qualified_field_base + ")";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,26 +80,37 @@ void EvolutionTest(const std::string &tests_data_path) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformTest() {
|
|
||||||
flatbuffers::Parser parser;
|
|
||||||
TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
|
|
||||||
|
|
||||||
auto test_conform = [](flatbuffers::Parser &parser1, const char *test,
|
void ConformTest() {
|
||||||
|
const char ref[] = "table T { A:int; } enum E:byte { A }";
|
||||||
|
|
||||||
|
auto test_conform = [](const char *ref, const char *test,
|
||||||
const char *expected_err) {
|
const char *expected_err) {
|
||||||
|
flatbuffers::Parser parser1;
|
||||||
|
TEST_EQ(parser1.Parse(ref), true);
|
||||||
flatbuffers::Parser parser2;
|
flatbuffers::Parser parser2;
|
||||||
TEST_EQ(parser2.Parse(test), true);
|
TEST_EQ(parser2.Parse(test), true);
|
||||||
auto err = parser2.ConformTo(parser1);
|
auto err = parser2.ConformTo(parser1);
|
||||||
TEST_NOTNULL(strstr(err.c_str(), expected_err));
|
if (*expected_err == '\0') {
|
||||||
|
TEST_EQ_STR(err.c_str(), expected_err);
|
||||||
|
} else {
|
||||||
|
TEST_NOTNULL(strstr(err.c_str(), expected_err));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test_conform(parser, "table T { A:byte; }", "types differ for field");
|
test_conform(ref, "table T { A:byte; }", "types differ for field: T.A");
|
||||||
test_conform(parser, "table T { B:int; A:int; }", "offsets differ for field");
|
test_conform(ref, "table T { B:int; A:int; }",
|
||||||
test_conform(parser, "table T { A:int = 1; }", "defaults differ for field");
|
"offsets differ for field: T.A");
|
||||||
test_conform(parser, "table T { B:float; }",
|
test_conform(ref, "table T { A:int = 1; }", "defaults differ for field: T.A");
|
||||||
"field renamed to different type");
|
test_conform(ref, "table T { B:float; }",
|
||||||
test_conform(parser, "enum E:byte { B, A }", "values differ for enum");
|
"field renamed to different type: T.B (renamed from T.A)");
|
||||||
test_conform(parser, "table T { }", "field deleted");
|
test_conform(ref, "enum E:byte { B, A }", "values differ for enum: A");
|
||||||
test_conform(parser, "table T { B:int; }", ""); //renaming a field is allowed
|
test_conform(ref, "table T { }", "field deleted: T.A");
|
||||||
|
test_conform(ref, "table T { B:int; }", ""); // renaming a field is allowed
|
||||||
|
|
||||||
|
const char ref2[] = "enum E:byte { A } table T2 { f:E; } ";
|
||||||
|
test_conform(ref2, "enum E:int32 { A } table T2 { df:byte; f:E; }",
|
||||||
|
"field renamed to different type: T2.df (renamed from T2.f)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnionDeprecationTest(const std::string& tests_data_path) {
|
void UnionDeprecationTest(const std::string& tests_data_path) {
|
||||||
|
|||||||
Reference in New Issue
Block a user