diff options
author | Derek Bailey <derekbailey@google.com> | 2023-05-02 23:50:20 -0700 |
---|---|---|
committer | Derek Bailey <derekbailey@google.com> | 2023-05-02 23:50:20 -0700 |
commit | fb4f6fb894804fee2160ab0085e828c7d8300b80 (patch) | |
tree | a12902ae613072a00cbc495037a6ab88ca1bf39d | |
parent | 19d8942943b1951e01806b508821c9d93a31c9b3 (diff) | |
download | flatbuffers-fb4f6fb894804fee2160ab0085e828c7d8300b80.tar.gz flatbuffers-fb4f6fb894804fee2160ab0085e828c7d8300b80.tar.bz2 flatbuffers-fb4f6fb894804fee2160ab0085e828c7d8300b80.zip |
fix possible null dereference for nested_root accessor
-rw-r--r-- | src/idl_gen_cpp.cpp | 44 | ||||
-rw-r--r-- | tests/monster_test_generated.h | 12 |
2 files changed, 33 insertions, 23 deletions
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 1b33016e..ad858473 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -987,7 +987,7 @@ class CppGenerator : public BaseGenerator { std::string UnionVectorVerifySignature(const EnumDef &enum_def) { const std::string name = Name(enum_def); - const std::string & type = opts_.scoped_enums ? name : "uint8_t"; + const std::string &type = opts_.scoped_enums ? name : "uint8_t"; return "bool Verify" + name + "Vector" + "(::flatbuffers::Verifier &verifier, " + "const ::flatbuffers::Vector<::flatbuffers::Offset<void>> " @@ -1807,7 +1807,7 @@ class CppGenerator : public BaseGenerator { field.value.type.element != BASE_TYPE_UTYPE)) { auto type = GenTypeNative(field.value.type, false, field); auto cpp_type = field.attributes.Lookup("cpp_type"); - const std::string & full_type = + const std::string &full_type = (cpp_type ? (IsVector(field.value.type) ? "std::vector<" + @@ -1954,9 +1954,10 @@ class CppGenerator : public BaseGenerator { if (!initializer_list.empty()) { initializer_list += ",\n "; } const auto cpp_type = field->attributes.Lookup("cpp_type"); const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); - const std::string & type_name = (cpp_type) ? cpp_type->constant - : GenTypeNative(type, /*invector*/ false, - *field, /*forcopy*/ true); + const std::string &type_name = + (cpp_type) ? cpp_type->constant + : GenTypeNative(type, /*invector*/ false, *field, + /*forcopy*/ true); const bool is_ptr = !(IsStruct(type) && field->native_inline) || (cpp_type && cpp_ptr_type->constant != "naked"); CodeWriter cw; @@ -1976,10 +1977,10 @@ class CppGenerator : public BaseGenerator { if (vec_type.base_type == BASE_TYPE_UTYPE) continue; const auto cpp_type = field->attributes.Lookup("cpp_type"); const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); - const std::string & type_name = (cpp_type) - ? cpp_type->constant - : GenTypeNative(vec_type, /*invector*/ true, - *field, /*forcopy*/ true); + const std::string &type_name = + (cpp_type) ? cpp_type->constant + : GenTypeNative(vec_type, /*invector*/ true, *field, + /*forcopy*/ true); const bool is_ptr = IsVectorOfPointers(*field) || (cpp_type && cpp_ptr_type->constant != "naked"); CodeWriter cw(" "); @@ -2733,9 +2734,10 @@ class CppGenerator : public BaseGenerator { if (!nfn.empty()) { code_.SetValue("CPP_NAME", nfn); code_ += " const {{CPP_NAME}} *{{FIELD_NAME}}_nested_root() const {"; + code_ += " const auto _f = {{FIELD_NAME}}();"; code_ += - " return " - "::flatbuffers::GetRoot<{{CPP_NAME}}>({{FIELD_NAME}}()->Data());"; + " return _f ? ::flatbuffers::GetRoot<{{CPP_NAME}}>(_f->Data())"; + code_ += " : nullptr;"; code_ += " }"; } @@ -2745,9 +2747,9 @@ class CppGenerator : public BaseGenerator { " const {"; // Both Data() and size() are const-methods, therefore call order // doesn't matter. - code_ += - " return flexbuffers::GetRoot({{FIELD_NAME}}()->Data(), " - "{{FIELD_NAME}}()->size());"; + code_ += " const auto _f = {{FIELD_NAME}}();"; + code_ += " return _f ? flexbuffers::GetRoot(_f->Data(), _f->size())"; + code_ += " : flexbuffers::Reference();"; code_ += " }"; } @@ -2835,8 +2837,9 @@ class CppGenerator : public BaseGenerator { // Generate code to do force_align for the vector. if (align > 1) { const auto vtype = field.value.type.VectorType(); - const std::string & type = IsStruct(vtype) ? WrapInNameSpace(*vtype.struct_def) - : GenTypeWire(vtype, "", false); + const std::string &type = IsStruct(vtype) + ? WrapInNameSpace(*vtype.struct_def) + : GenTypeWire(vtype, "", false); return "_fbb.ForceVectorAlignment(" + field_size + ", sizeof(" + type + "), " + std::to_string(static_cast<long long>(align)) + ");"; } @@ -3357,8 +3360,9 @@ class CppGenerator : public BaseGenerator { } case BASE_TYPE_UTYPE: { value = StripUnionType(value); - const std::string & type = opts_.scoped_enums ? Name(*field.value.type.enum_def) - : "uint8_t"; + const std::string &type = opts_.scoped_enums + ? Name(*field.value.type.enum_def) + : "uint8_t"; auto enum_value = "__va->_" + value + "[i].type"; if (!opts_.scoped_enums) enum_value = "static_cast<uint8_t>(" + enum_value + ")"; @@ -3424,7 +3428,7 @@ class CppGenerator : public BaseGenerator { } } else { // _o->field ? CreateT(_fbb, _o->field.get(), _rehasher); - const std::string & type = field.value.type.struct_def->name; + const std::string &type = field.value.type.struct_def->name; code += value + " ? Create" + type; code += "(_fbb, " + value; if (!field.native_inline) code += GenPtrGet(field); @@ -3810,7 +3814,7 @@ class CppGenerator : public BaseGenerator { const auto field_type = GenTypeGet(type, " ", is_array ? "" : "const ", is_array ? "" : " &", true); auto member = Name(*field) + "_"; - const std::string & value = + const std::string &value = is_scalar ? "::flatbuffers::EndianScalar(" + member + ")" : member; code_.SetValue("FIELD_NAME", Name(*field)); diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index eebb0c6f..d11788e1 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -1487,7 +1487,9 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { return GetPointer<::flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER); } const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const { - return ::flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data()); + const auto _f = testnestedflatbuffer(); + return _f ? ::flatbuffers::GetRoot<MyGame::Example::Monster>(_f->Data()) + : nullptr; } const MyGame::Example::Stat *testempty() const { return GetPointer<const MyGame::Example::Stat *>(VT_TESTEMPTY); @@ -1592,7 +1594,9 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { return GetPointer<::flatbuffers::Vector<uint8_t> *>(VT_FLEX); } flexbuffers::Reference flex_flexbuffer_root() const { - return flexbuffers::GetRoot(flex()->Data(), flex()->size()); + const auto _f = flex(); + return _f ? flexbuffers::GetRoot(_f->Data(), _f->size()) + : flexbuffers::Reference(); } const ::flatbuffers::Vector<const MyGame::Example::Test *> *test5() const { return GetPointer<const ::flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5); @@ -1722,7 +1726,9 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { return GetPointer<::flatbuffers::Vector<uint8_t> *>(VT_TESTREQUIREDNESTEDFLATBUFFER); } const MyGame::Example::Monster *testrequirednestedflatbuffer_nested_root() const { - return ::flatbuffers::GetRoot<MyGame::Example::Monster>(testrequirednestedflatbuffer()->Data()); + const auto _f = testrequirednestedflatbuffer(); + return _f ? ::flatbuffers::GetRoot<MyGame::Example::Monster>(_f->Data()) + : nullptr; } const ::flatbuffers::Vector<::flatbuffers::Offset<MyGame::Example::Stat>> *scalar_key_sorted_tables() const { return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<MyGame::Example::Stat>> *>(VT_SCALAR_KEY_SORTED_TABLES); |