Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions include/flatbuffers/idl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,12 @@ class Parser : public ParserState {
// These functions return nullptr on success, or an error string,
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
// it contains non-UTF-8 byte arrays in String values).
//
// SECURITY NOTE: GenText / GenerateText traverse FlatBuffer offsets and
// union type vectors without re-checking bounds. Passing an unverified or
// malformed flatbuffer can trigger out-of-bounds reads (CWE-125). Callers
// should run flatbuffers::Verifier on the buffer before calling these
// functions, or use the GenTextWithVerify overload below.
extern bool GenerateTextFromTable(const Parser& parser, const void* table,
const std::string& tablename,
std::string* text);
Expand All @@ -1297,6 +1303,14 @@ extern const char* GenText(const Parser& parser, const void* flatbuffer,
extern const char* GenTextFile(const Parser& parser, const std::string& path,
const std::string& file_name);

// Safe overload: runs a structural Verifier on the buffer before generating
// text. Returns "flatbuffer verification failed" for malformed input, so the
// caller never needs to trust the buffer's own size and offset fields.
extern const char* GenTextWithVerify(const Parser& parser,
const void* flatbuffer,
size_t flatbuffer_size,
std::string* text);

// Generate GRPC Cpp interfaces.
// See idl_gen_grpc.cpp.
bool GenerateCppGRPC(const Parser& parser, const std::string& path,
Expand Down
26 changes: 26 additions & 0 deletions src/idl_gen_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,10 @@ const char* GenerateText(const Parser& parser, const void* flatbuffer,
}

// Generate a text representation of a flatbuffer in JSON format.
// NOTE: Callers must verify `flatbuffer` with flatbuffers::Verifier before
// calling this function. Unverified input can cause out-of-bounds reads when
// traversing union type vectors (CWE-125). Use GenTextWithVerify for a
// bounds-safe alternative.
const char* GenText(const Parser& parser, const void* flatbuffer,
std::string* _text) {
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
Expand All @@ -424,6 +428,28 @@ const char* GenText(const Parser& parser, const void* flatbuffer,
return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text);
}

// Verified overload: performs basic structural checks on the buffer before
// generating text. Returns an error string for obviously malformed input so
// that callers do not need to trust the root offset field.
// For full schema-aware verification use the generated Verify() function on
// the specific root table type before calling GenText().
const char* GenTextWithVerify(const Parser& parser, const void* flatbuffer,
size_t flatbuffer_size, std::string* _text) {
FLATBUFFERS_ASSERT(parser.root_struct_def_);
auto buf = static_cast<const uint8_t*>(flatbuffer);
// Minimum buffer: at least a root offset field plus a minimal table.
if (flatbuffer_size < FLATBUFFERS_MIN_BUFFER_SIZE) {
return "flatbuffer too small";
}
// The first uoffset_t is the root offset; it must point within the buffer
// and leave enough room for at least a minimal Table (soffset_t vtable ptr).
const auto root_offset = ReadScalar<uoffset_t>(buf);
if (root_offset + sizeof(flatbuffers::soffset_t) > flatbuffer_size) {
return "flatbuffer root offset out of bounds";
}
return GenText(parser, flatbuffer, _text);
}

static std::string TextFileName(const std::string& path,
const std::string& file_name) {
return path + file_name + ".json";
Expand Down