Skip to content

Commit 3a8d697

Browse files
committed
Fix Stack Overflow DoS via Unbounded Recursion in idl_gen_text.cpp
1 parent 4e582b0 commit 3a8d697

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

src/idl_gen_text.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,16 @@ struct JsonPrinter {
178178
return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
179179
}
180180

181+
struct DepthGuard {
182+
int *depth_;
183+
DepthGuard(int *depth) : depth_(depth) { --(*depth_); }
184+
~DepthGuard() { ++(*depth_); }
185+
};
186+
181187
const char* PrintOffset(const void* val, const Type& type, int indent,
182188
const uint8_t* prev_val, soffset_t vector_index) {
189+
if (depth_limit == 0) return "error: text generation depth limit exceeded";
190+
DepthGuard depth_guard(&depth_limit);
183191
switch (type.base_type) {
184192
case BASE_TYPE_UNION: {
185193
// If this assert hits, you have an corrupt buffer, a union type field
@@ -314,6 +322,8 @@ struct JsonPrinter {
314322
// and bracketed by "{}"
315323
const char* GenStruct(const StructDef& struct_def, const Table* table,
316324
int indent) {
325+
if (depth_limit == 0) return "error: text generation depth limit exceeded";
326+
DepthGuard depth_guard(&depth_limit);
317327
text += '{';
318328
int fieldout = 0;
319329
const uint8_t* prev_val = nullptr;
@@ -372,12 +382,13 @@ struct JsonPrinter {
372382
}
373383

374384
JsonPrinter(const Parser& parser, std::string& dest)
375-
: opts(parser.opts), text(dest) {
385+
: opts(parser.opts), text(dest), depth_limit(FLATBUFFERS_MAX_PARSING_DEPTH) {
376386
text.reserve(1024); // Reduce amount of inevitable reallocs.
377387
}
378388

379389
const IDLOptions& opts;
380390
std::string& text;
391+
int depth_limit;
381392
};
382393

383394
static const char* GenerateTextImpl(const Parser& parser, const Table* table,

0 commit comments

Comments
 (0)