Skip to content

Commit 2b107e2

Browse files
[fuzzer] Adds code generation target. (#8795)
* adds code generation fuzzer target. * add buffer verification * add table verification in codegen fuzzer --------- Co-authored-by: Björn Harrtell <[email protected]>
1 parent 84f4b83 commit 2b107e2

File tree

13 files changed

+495
-10
lines changed

13 files changed

+495
-10
lines changed

src/idl_gen_ts.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct NsDefinition {
4747
std::string path;
4848
std::string filepath;
4949
std::string symbolic_name;
50-
const Namespace* ns;
50+
const Namespace* ns = nullptr;
5151
std::map<std::string, const Definition*> definitions;
5252
};
5353

@@ -258,7 +258,7 @@ class TsGenerator : public BaseGenerator {
258258
nsDef.path = root;
259259
nsDef.symbolic_name = file_name_;
260260
nsDef.filepath = path_ + file_name_ + ".ts";
261-
nsDef.ns = new Namespace();
261+
nsDef.ns = parser_.empty_namespace_;
262262
ns_defs_[nsDef.path] = nsDef;
263263
}
264264

tests/fuzzer/CMakeLists.txt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,67 @@ set(FlatBuffers_Library_SRCS
120120
${FLATBUFFERS_DIR}/tests/64bit/test_64bit_bfbs_generated.h
121121
)
122122

123+
set(FlatBuffers_Compiler_SRCS
124+
${FLATBUFFERS_DIR}/src/idl_gen_binary.cpp
125+
${FLATBUFFERS_DIR}/src/idl_gen_text.cpp
126+
${FLATBUFFERS_DIR}/src/idl_gen_cpp.cpp
127+
${FLATBUFFERS_DIR}/src/idl_gen_csharp.cpp
128+
${FLATBUFFERS_DIR}/src/idl_gen_dart.cpp
129+
${FLATBUFFERS_DIR}/src/idl_gen_kotlin.cpp
130+
${FLATBUFFERS_DIR}/src/idl_gen_kotlin_kmp.cpp
131+
${FLATBUFFERS_DIR}/src/idl_gen_go.cpp
132+
${FLATBUFFERS_DIR}/src/idl_gen_java.cpp
133+
${FLATBUFFERS_DIR}/src/idl_gen_ts.cpp
134+
${FLATBUFFERS_DIR}/src/idl_gen_php.cpp
135+
${FLATBUFFERS_DIR}/src/idl_gen_python.cpp
136+
${FLATBUFFERS_DIR}/src/idl_gen_lobster.cpp
137+
${FLATBUFFERS_DIR}/src/idl_gen_rust.cpp
138+
${FLATBUFFERS_DIR}/src/idl_gen_fbs.cpp
139+
${FLATBUFFERS_DIR}/src/idl_gen_grpc.cpp
140+
${FLATBUFFERS_DIR}/src/idl_gen_json_schema.cpp
141+
${FLATBUFFERS_DIR}/src/idl_gen_swift.cpp
142+
${FLATBUFFERS_DIR}/src/file_name_saving_file_manager.cpp
143+
${FLATBUFFERS_DIR}/src/file_binary_writer.cpp
144+
${FLATBUFFERS_DIR}/src/file_writer.cpp
145+
${FLATBUFFERS_DIR}/src/idl_namer.h
146+
${FLATBUFFERS_DIR}/src/namer.h
147+
${FLATBUFFERS_DIR}/src/flatc.cpp
148+
# ${FLATBUFFERS_DIR}/src/flatc_main.cpp
149+
${FLATBUFFERS_DIR}/src/bfbs_gen.h
150+
${FLATBUFFERS_DIR}/src/bfbs_gen_lua.h
151+
${FLATBUFFERS_DIR}/src/bfbs_gen_nim.h
152+
${FLATBUFFERS_DIR}/src/bfbs_namer.h
153+
${FLATBUFFERS_DIR}/include/codegen/idl_namer.h
154+
${FLATBUFFERS_DIR}/include/codegen/namer.h
155+
${FLATBUFFERS_DIR}/include/codegen/python.h
156+
${FLATBUFFERS_DIR}/include/codegen/python.cc
157+
${FLATBUFFERS_DIR}/include/flatbuffers/code_generators.h
158+
${FLATBUFFERS_DIR}/src/binary_annotator.h
159+
${FLATBUFFERS_DIR}/src/binary_annotator.cpp
160+
${FLATBUFFERS_DIR}/src/annotated_binary_text_gen.h
161+
${FLATBUFFERS_DIR}/src/annotated_binary_text_gen.cpp
162+
${FLATBUFFERS_DIR}/src/bfbs_gen_lua.cpp
163+
${FLATBUFFERS_DIR}/src/bfbs_gen_nim.cpp
164+
${FLATBUFFERS_DIR}/src/code_generators.cpp
165+
${FLATBUFFERS_DIR}/grpc/src/compiler/schema_interface.h
166+
${FLATBUFFERS_DIR}/grpc/src/compiler/cpp_generator.h
167+
${FLATBUFFERS_DIR}/grpc/src/compiler/cpp_generator.cc
168+
${FLATBUFFERS_DIR}/grpc/src/compiler/go_generator.h
169+
${FLATBUFFERS_DIR}/grpc/src/compiler/go_generator.cc
170+
${FLATBUFFERS_DIR}/grpc/src/compiler/java_generator.h
171+
${FLATBUFFERS_DIR}/grpc/src/compiler/java_generator.cc
172+
${FLATBUFFERS_DIR}/grpc/src/compiler/python_generator.h
173+
${FLATBUFFERS_DIR}/grpc/src/compiler/python_generator.cc
174+
${FLATBUFFERS_DIR}/grpc/src/compiler/swift_generator.h
175+
${FLATBUFFERS_DIR}/grpc/src/compiler/swift_generator.cc
176+
${FLATBUFFERS_DIR}/grpc/src/compiler/ts_generator.h
177+
${FLATBUFFERS_DIR}/grpc/src/compiler/ts_generator.cc
178+
)
179+
123180
include_directories(${FLATBUFFERS_DIR}/include)
124181
include_directories(${FLATBUFFERS_DIR}/tests)
125182
include_directories(${FLATBUFFERS_DIR}/src)
183+
include_directories(${FLATBUFFERS_DIR}/grpc)
126184

127185
add_library(flatbuffers_fuzzed STATIC ${FlatBuffers_Library_SRCS})
128186
# Use PUBLIC to force 'fuzzer_config' for all dependent targets
@@ -156,6 +214,11 @@ target_link_libraries(flexverifier_fuzzer PRIVATE flatbuffers_fuzzed)
156214

157215
add_executable(monster_fuzzer flatbuffers_monster_fuzzer.cc)
158216
target_link_libraries(monster_fuzzer PRIVATE flatbuffers_fuzzed)
217+
218+
add_executable(codegen_fuzzer flatbuffers_codegen_fuzzer.cc ${FlatBuffers_Compiler_SRCS})
219+
target_link_libraries(codegen_fuzzer PRIVATE flatbuffers_fuzzed)
220+
target_compile_definitions(codegen_fuzzer PRIVATE assert=fuzzer_assert_impl)
221+
159222
add_custom_command(
160223
TARGET monster_fuzzer PRE_BUILD
161224
COMMAND ${CMAKE_COMMAND} -E copy

tests/fuzzer/codegen_json.dict

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"struct"
2+
"table"
3+
"enum"
4+
"union"
5+
"include"
6+
"namespace"
7+
"attribute"
8+
"null"
9+
"NULL"
10+
"byte"
11+
"int8"
12+
"ubyte"
13+
"uint8"
14+
"bool"
15+
"short"
16+
"int16"
17+
"ushort"
18+
"uint16"
19+
"int"
20+
"int32"
21+
"uint"
22+
"uint32"
23+
"float"
24+
"float32"
25+
"long"
26+
"int64"
27+
"ulong"
28+
"uint64"
29+
"double"
30+
"float64"
31+
"root_type"
32+
"file_identifier"
33+
"file_extension"
34+
"rpc_service"
35+
"streaming"
36+
"idempotent"
37+
"key"
38+
"hash"
39+
"fnv1_32"
40+
"fnv1_64"
41+
"fnv1a_32"
42+
"fnv1a_64"
43+
"deprecated"
44+
"required"
45+
"nested_flatbuffer"
46+
"flexbuffer"
47+
"native_inline"
48+
"force_align"
49+
"bit_flags"
50+
"csharp_partial"
51+
"private"
52+
"cpp_type"
53+
"cpp_ptr_type"
54+
"cpp_ptr_type_get"
55+
"{"
56+
"}"
57+
"["
58+
"]"
59+
"\""
60+
"'"
61+
"\\"
62+
"//"
63+
":"
64+
","
65+
" "
66+
"\\n"
67+
"\\r"
68+
"/*"
69+
"*/"
70+
"true"
71+
"false"
72+
"null"
73+
"\\u"
74+
"\\b"
75+
"\\f"
76+
"\\t"
77+
"."
78+
"e"
79+
"e+"
80+
"e-"
81+
"E"
82+
"E+"
83+
"E-"
84+
"0x"
85+
"p"
86+
"a"
87+
"b"
88+
"Monster"
89+
"pos"
90+
"hp"
91+
"name"
92+
"weapons"
93+
"damage"
94+
"equipped_type"
95+
"equipped"
96+
"inventory"
97+
"vector_of_longs"
98+
"vector_of_doubles"
99+
"test_type"
100+
"test"
101+
"test1"
102+
"test2"
103+
"test4"
104+
"test3"
105+
"test5"
106+
"enemy"
107+
"Weapon"
108+
"Green"
109+
"Red"
110+
"Blue"
111+
"testarrayofstring"
112+
"testarrayofbools"
113+
"testbool"
114+
"flex"
115+
"Color"
116+
"Vec3"
117+
"Stat"
118+
"Referrable"
119+
"Any"
120+
"TestSimpleTableWithEnum"
121+
"Race"
122+
"LongEnum"
123+
"Test"
124+
"Ability"
125+
"StructOfStructs"
126+
"StructOfStructsOfStructs"
127+
"TypeAliases"
128+
"MonsterStorage"
129+
"Store"
130+
"Retrieve"
131+
"GetMaxHitPoint"
132+
"GetMinMaxHitPoints"
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#include <stddef.h>
2+
#include <stdint.h>
3+
#include <string>
4+
#include "flatbuffers/idl.h" // For Parser and generation functions
5+
#include "test_init.h"
6+
#include <memory>
7+
#include <flatbuffers/flatc.h>
8+
#include "idl_gen_cpp.h" // For C++ generator
9+
#include <idl_gen_csharp.h>
10+
#include <iostream>
11+
#include "flatbuffers/code_generator.h"
12+
#include <idl_gen_binary.h>
13+
#include <idl_gen_dart.h>
14+
#include <idl_gen_fbs.h>
15+
#include <idl_gen_go.h>
16+
#include <idl_gen_java.h>
17+
#include <idl_gen_json_schema.h>
18+
#include <idl_gen_kotlin.h>
19+
#include <idl_gen_kotlin.h>
20+
#include <idl_gen_lobster.h>
21+
#include <bfbs_gen_lua.h>
22+
#include <bfbs_gen_nim.h>
23+
#include <idl_gen_python.h>
24+
#include <idl_gen_php.h>
25+
#include <idl_gen_rust.h>
26+
#include <idl_gen_text.h>
27+
#include <idl_gen_swift.h>
28+
#include <idl_gen_ts.h>
29+
30+
static constexpr size_t kMinInputLength = 1;
31+
static constexpr size_t kMaxInputLength = 16384;
32+
33+
static constexpr uint8_t flags_strict_json = 0x80;
34+
static constexpr uint8_t flags_skip_unexpected_fields_in_json = 0x40;
35+
static constexpr uint8_t flags_allow_non_utf8 = 0x20;
36+
37+
// Utility for test run.
38+
OneTimeTestInit OneTimeTestInit::one_time_init_;
39+
40+
static const char* g_program_name = nullptr;
41+
42+
static void Warn(const flatbuffers::FlatCompiler* flatc,
43+
const std::string& warn, bool show_exe_name) {
44+
(void)flatc;
45+
if (show_exe_name) {
46+
printf("%s: ", g_program_name);
47+
}
48+
fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str());
49+
}
50+
51+
static void Error(const flatbuffers::FlatCompiler* flatc,
52+
const std::string& err, bool usage, bool show_exe_name) {
53+
if (show_exe_name) {
54+
printf("%s: ", g_program_name);
55+
}
56+
if (usage && flatc) {
57+
fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
58+
}
59+
fprintf(stderr, "\nerror:\n %s\n\n", err.c_str());
60+
exit(1);
61+
}
62+
63+
namespace flatbuffers {
64+
void LogCompilerWarn(const std::string& warn) {
65+
Warn(static_cast<const flatbuffers::FlatCompiler*>(nullptr), warn, true);
66+
}
67+
void LogCompilerError(const std::string& err) {
68+
Error(static_cast<const flatbuffers::FlatCompiler*>(nullptr), err, false,
69+
true);
70+
}
71+
} // namespace flatbuffers
72+
73+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
74+
// Reserve one byte for Parser flags and one byte for repetition counter.
75+
if (size < 3) return 0;
76+
const uint8_t flags = data[0];
77+
(void)data[1]; // reserved
78+
data += 2;
79+
size -= 2; // bypass
80+
81+
const std::string original(reinterpret_cast<const char*>(data), size);
82+
auto input = std::string(original.c_str()); // until '\0'
83+
if (input.size() < kMinInputLength || input.size() > kMaxInputLength)
84+
return 0;
85+
86+
flatbuffers::IDLOptions opts;
87+
opts.strict_json = (flags & flags_strict_json);
88+
opts.skip_unexpected_fields_in_json =
89+
(flags & flags_skip_unexpected_fields_in_json);
90+
opts.allow_non_utf8 = (flags & flags_allow_non_utf8);
91+
92+
flatbuffers::Parser parser(opts);
93+
94+
// Guarantee 0-termination in the input.
95+
auto parse_input = input.c_str();
96+
97+
// Parse the input schema
98+
if (parser.Parse(parse_input)) {
99+
parser.Serialize();
100+
const uint8_t* buf = parser.builder_.GetBufferPointer();
101+
flatbuffers::Verifier verifier(buf,
102+
parser.builder_.GetSize());
103+
TEST_EQ(true, reflection::VerifySchemaBuffer(verifier));
104+
105+
auto root = flatbuffers::GetRoot<flatbuffers::Table>(buf);
106+
if (verifier.VerifyTableStart(buf) && root->VerifyTableStart(verifier)) {
107+
if (parser.root_struct_def_) {
108+
std::string json_output;
109+
flatbuffers::GenText(parser, parser.builder_.GetBufferPointer(),
110+
&json_output);
111+
}
112+
}
113+
114+
std::string temp_filename = "fuzzer_generated";
115+
116+
const std::string flatbuffers_version(flatbuffers::FLATBUFFERS_VERSION());
117+
std::vector<std::unique_ptr<flatbuffers::CodeGenerator>> generators;
118+
generators.emplace_back(flatbuffers::NewBinaryCodeGenerator());
119+
generators.emplace_back(flatbuffers::NewCppCodeGenerator());
120+
generators.emplace_back(flatbuffers::NewCSharpCodeGenerator());
121+
generators.emplace_back(flatbuffers::NewDartCodeGenerator());
122+
generators.emplace_back(flatbuffers::NewFBSCodeGenerator());
123+
generators.emplace_back(flatbuffers::NewGoCodeGenerator());
124+
generators.emplace_back(flatbuffers::NewJavaCodeGenerator());
125+
generators.emplace_back(flatbuffers::NewJsonSchemaCodeGenerator());
126+
generators.emplace_back(flatbuffers::NewKotlinCodeGenerator());
127+
generators.emplace_back(flatbuffers::NewKotlinKMPCodeGenerator());
128+
generators.emplace_back(flatbuffers::NewLobsterCodeGenerator());
129+
generators.emplace_back(flatbuffers::NewLuaBfbsGenerator(flatbuffers_version));
130+
generators.emplace_back(flatbuffers::NewNimBfbsGenerator(flatbuffers_version));
131+
generators.emplace_back(flatbuffers::NewPythonCodeGenerator());
132+
generators.emplace_back(flatbuffers::NewPhpCodeGenerator());
133+
generators.emplace_back(flatbuffers::NewRustCodeGenerator());
134+
generators.emplace_back(flatbuffers::NewTextCodeGenerator());
135+
generators.emplace_back(flatbuffers::NewSwiftCodeGenerator());
136+
generators.emplace_back(flatbuffers::NewTsCodeGenerator());
137+
138+
for (auto& gen : generators) {
139+
auto p = gen.get();
140+
std::string temp_path = "/tmp/";
141+
auto status = p->GenerateCode(parser, temp_path, "fuzzer_generated");
142+
if (status != flatbuffers::CodeGenerator::Status::OK) {
143+
TEST_OUTPUT_LINE("GenerateCode failed %d", status);
144+
}
145+
146+
// test gRPC code generation
147+
auto grpc_status =
148+
p->GenerateGrpcCode(parser, temp_path, "fuzzer_generated");
149+
if (grpc_status != flatbuffers::CodeGenerator::Status::OK) {
150+
TEST_OUTPUT_LINE("GenerateGrpcCode failed %d", grpc_status);
151+
}
152+
}
153+
}
154+
155+
return 0;
156+
}

0 commit comments

Comments
 (0)