Coverage Report

Created: 2026-02-26 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flatbuffers/tests/fuzzer/flatbuffers_codegen_fuzzer.cc
Line
Count
Source
1
#include <bfbs_gen_lua.h>
2
#include <bfbs_gen_nim.h>
3
#include <flatbuffers/flatc.h>
4
#include <idl_gen_binary.h>
5
#include <idl_gen_csharp.h>
6
#include <idl_gen_dart.h>
7
#include <idl_gen_fbs.h>
8
#include <idl_gen_go.h>
9
#include <idl_gen_java.h>
10
#include <idl_gen_json_schema.h>
11
#include <idl_gen_kotlin.h>
12
#include <idl_gen_lobster.h>
13
#include <idl_gen_php.h>
14
#include <idl_gen_python.h>
15
#include <idl_gen_rust.h>
16
#include <idl_gen_swift.h>
17
#include <idl_gen_text.h>
18
#include <idl_gen_ts.h>
19
#include <stddef.h>
20
#include <stdint.h>
21
22
#include <iostream>
23
#include <memory>
24
#include <string>
25
26
#include "flatbuffers/code_generator.h"
27
#include "flatbuffers/idl.h"  // For Parser and generation functions
28
#include "idl_gen_cpp.h"      // For C++ generator
29
#include "test_init.h"
30
31
static constexpr size_t kMinInputLength = 1;
32
static constexpr size_t kMaxInputLength = 16384;
33
34
static constexpr uint8_t flags_strict_json = 0x80;
35
static constexpr uint8_t flags_skip_unexpected_fields_in_json = 0x40;
36
static constexpr uint8_t flags_allow_non_utf8 = 0x20;
37
38
// Utility for test run.
39
OneTimeTestInit OneTimeTestInit::one_time_init_;
40
41
static const char* g_program_name = nullptr;
42
43
static void Warn(const flatbuffers::FlatCompiler* flatc,
44
0
                 const std::string& warn, bool show_exe_name) {
45
0
  (void)flatc;
46
0
  if (show_exe_name) {
47
0
    printf("%s: ", g_program_name);
48
0
  }
49
0
  fprintf(stderr, "\nwarning:\n  %s\n\n", warn.c_str());
50
0
}
51
52
static void Error(const flatbuffers::FlatCompiler* flatc,
53
0
                  const std::string& err, bool usage, bool show_exe_name) {
54
0
  if (show_exe_name) {
55
0
    printf("%s: ", g_program_name);
56
0
  }
57
0
  if (usage && flatc) {
58
0
    fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
59
0
  }
60
0
  fprintf(stderr, "\nerror:\n  %s\n\n", err.c_str());
61
0
  exit(1);
62
0
}
63
64
namespace flatbuffers {
65
0
void LogCompilerWarn(const std::string& warn) {
66
0
  Warn(static_cast<const flatbuffers::FlatCompiler*>(nullptr), warn, true);
67
0
}
68
0
void LogCompilerError(const std::string& err) {
69
0
  Error(static_cast<const flatbuffers::FlatCompiler*>(nullptr), err, false,
70
0
        true);
71
0
}
72
}  // namespace flatbuffers
73
74
561
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
75
  // Reserve one byte for Parser flags and one byte for repetition counter.
76
561
  if (size < 3) return 0;
77
561
  const uint8_t flags = data[0];
78
561
  (void)data[1];  //  reserved
79
561
  data += 2;
80
561
  size -= 2;  // bypass
81
82
561
  const std::string original(reinterpret_cast<const char*>(data), size);
83
561
  auto input = std::string(original.c_str());  // until '\0'
84
561
  if (input.size() < kMinInputLength || input.size() > kMaxInputLength)
85
23
    return 0;
86
87
538
  flatbuffers::IDLOptions opts;
88
538
  opts.strict_json = (flags & flags_strict_json);
89
538
  opts.skip_unexpected_fields_in_json =
90
538
      (flags & flags_skip_unexpected_fields_in_json);
91
538
  opts.allow_non_utf8 = (flags & flags_allow_non_utf8);
92
93
538
  flatbuffers::Parser parser(opts);
94
95
  // Guarantee 0-termination in the input.
96
538
  auto parse_input = input.c_str();
97
98
  // Parse the input schema
99
538
  if (parser.Parse(parse_input)) {
100
0
    parser.Serialize();
101
0
    const uint8_t* buf = parser.builder_.GetBufferPointer();
102
0
    flatbuffers::Verifier verifier(buf, parser.builder_.GetSize());
103
0
    TEST_EQ(true, reflection::VerifySchemaBuffer(verifier));
104
105
0
    auto root = flatbuffers::GetRoot<flatbuffers::Table>(buf);
106
0
    if (verifier.VerifyTableStart(buf) && root->VerifyTableStart(verifier)) {
107
0
      if (parser.root_struct_def_) {
108
0
        std::string json_output;
109
0
        flatbuffers::GenText(parser, parser.builder_.GetBufferPointer(),
110
0
                             &json_output);
111
0
      }
112
0
    }
113
114
0
    std::string temp_filename = "fuzzer_generated";
115
116
0
    const std::string flatbuffers_version(flatbuffers::FLATBUFFERS_VERSION());
117
0
    std::vector<std::unique_ptr<flatbuffers::CodeGenerator>> generators;
118
0
    generators.emplace_back(flatbuffers::NewBinaryCodeGenerator());
119
0
    generators.emplace_back(flatbuffers::NewCppCodeGenerator());
120
0
    generators.emplace_back(flatbuffers::NewCSharpCodeGenerator());
121
0
    generators.emplace_back(flatbuffers::NewDartCodeGenerator());
122
0
    generators.emplace_back(flatbuffers::NewFBSCodeGenerator());
123
0
    generators.emplace_back(flatbuffers::NewGoCodeGenerator());
124
0
    generators.emplace_back(flatbuffers::NewJavaCodeGenerator());
125
0
    generators.emplace_back(flatbuffers::NewJsonSchemaCodeGenerator());
126
0
    generators.emplace_back(flatbuffers::NewKotlinCodeGenerator());
127
0
    generators.emplace_back(flatbuffers::NewKotlinKMPCodeGenerator());
128
0
    generators.emplace_back(flatbuffers::NewLobsterCodeGenerator());
129
0
    generators.emplace_back(
130
0
        flatbuffers::NewLuaBfbsGenerator(flatbuffers_version));
131
0
    generators.emplace_back(
132
0
        flatbuffers::NewNimBfbsGenerator(flatbuffers_version));
133
0
    generators.emplace_back(flatbuffers::NewPythonCodeGenerator());
134
0
    generators.emplace_back(flatbuffers::NewPhpCodeGenerator());
135
0
    generators.emplace_back(flatbuffers::NewRustCodeGenerator());
136
0
    generators.emplace_back(flatbuffers::NewTextCodeGenerator());
137
0
    generators.emplace_back(flatbuffers::NewSwiftCodeGenerator());
138
0
    generators.emplace_back(flatbuffers::NewTsCodeGenerator());
139
140
0
    for (auto& gen : generators) {
141
0
      auto p = gen.get();
142
0
      std::string temp_path = "/tmp/";
143
0
      auto status = p->GenerateCode(parser, temp_path, "fuzzer_generated");
144
0
      if (status != flatbuffers::CodeGenerator::Status::OK) {
145
0
        TEST_OUTPUT_LINE("GenerateCode failed %d", status);
146
0
      }
147
148
      // test gRPC code generation
149
0
      auto grpc_status =
150
0
          p->GenerateGrpcCode(parser, temp_path, "fuzzer_generated");
151
0
      if (grpc_status != flatbuffers::CodeGenerator::Status::OK) {
152
0
        TEST_OUTPUT_LINE("GenerateGrpcCode failed %d", grpc_status);
153
0
      }
154
0
    }
155
0
  }
156
157
538
  return 0;
158
561
}