Support binary serialization of protos.
diff --git a/examples/libfuzzer/CMakeLists.txt b/examples/libfuzzer/CMakeLists.txt
index 173363c..f6f2dbf 100644
--- a/examples/libfuzzer/CMakeLists.txt
+++ b/examples/libfuzzer/CMakeLists.txt
@@ -12,26 +12,32 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-protobuf_generate_cpp(LIB_FUZZER_EXAMPLE_PROTO_SRCS
- LIB_FUZZER_EXAMPLE_PROTO_HDRS
- libfuzzer_example.proto)
-add_executable(libfuzzer_example
- libfuzzer_example.cc
- ${LIB_FUZZER_EXAMPLE_PROTO_SRCS})
-target_link_libraries(libfuzzer_example
- protobuf-mutator
- ${LIB_PROTO_MUTATOR_FUZZER_LIBRARIES})
-set_property(TARGET libfuzzer_example
- PROPERTY COMPILE_FLAGS ${FUZZING_FLAGS})
-set_property(TARGET libfuzzer_example
- PROPERTY LINK_FLAGS ${FUZZING_FLAGS})
-
add_executable(libfuzzer_example_test
libfuzzer_example_test.cc)
-add_dependencies(libfuzzer_example_test libfuzzer_example)
target_link_libraries(libfuzzer_example_test
${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT})
add_test(test.libfuzzer_example_test libfuzzer_example_test --gtest_color=yes AUTO)
-
add_dependencies(check libfuzzer_example_test)
+
+protobuf_generate_cpp(LIB_FUZZER_EXAMPLE_PROTO_SRCS
+ LIB_FUZZER_EXAMPLE_PROTO_HDRS
+ libfuzzer_example.proto)
+
+add_library(fuzzer-example-proto
+ ${LIB_FUZZER_EXAMPLE_PROTO_SRCS})
+set_property(TARGET fuzzer-example-proto
+ PROPERTY COMPILE_FLAGS ${NO_FUZZING_FLAGS})
+
+foreach(fuzzer libfuzzer_example libfuzzer_bin_example)
+ add_executable(${fuzzer} ${fuzzer}.cc)
+ target_link_libraries(${fuzzer}
+ fuzzer-example-proto
+ protobuf-mutator
+ ${LIB_PROTO_MUTATOR_FUZZER_LIBRARIES})
+ set_property(TARGET ${fuzzer}
+ PROPERTY COMPILE_FLAGS ${FUZZING_FLAGS})
+ set_property(TARGET ${fuzzer}
+ PROPERTY LINK_FLAGS ${FUZZING_FLAGS})
+ add_dependencies(libfuzzer_example_test ${fuzzer})
+endforeach(fuzzer)
diff --git a/examples/libfuzzer/libfuzzer_bin_example.cc b/examples/libfuzzer/libfuzzer_bin_example.cc
new file mode 100644
index 0000000..87dd7fd
--- /dev/null
+++ b/examples/libfuzzer/libfuzzer_bin_example.cc
@@ -0,0 +1,47 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstddef>
+#include <cstdint>
+
+#include "examples/libfuzzer/libfuzzer_example.pb.h"
+#include "src/libfuzzer_protobuf_mutator.h"
+
+using libfuzzer_example::Msg;
+
+extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
+ size_t max_size, unsigned int seed) {
+ return protobuf_mutator::MutateBinaryMessage<Msg>(data, size, max_size, seed);
+}
+
+extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
+ const uint8_t* data2, size_t size2,
+ uint8_t* out, size_t max_out_size,
+ unsigned int seed) {
+ return protobuf_mutator::CrossOverBinaryMessages<Msg>(
+ data1, size1, data2, size2, out, max_out_size, seed);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ libfuzzer_example::Msg message;
+ protobuf_mutator::ParseBinaryMessage(data, size, &message);
+
+ // Emulate a bug.
+ if (message.optional_bool() &&
+ std::hash<std::string>()(message.optional_string()) % 1000 == 9) {
+ abort();
+ }
+
+ return 0;
+}
diff --git a/examples/libfuzzer/libfuzzer_example_test.cc b/examples/libfuzzer/libfuzzer_example_test.cc
index 8401a9e..a142553 100644
--- a/examples/libfuzzer/libfuzzer_example_test.cc
+++ b/examples/libfuzzer/libfuzzer_example_test.cc
@@ -32,3 +32,17 @@
// Cleanup.
EXPECT_EQ(0, std::system((std::string("rm -rf ") + dir).c_str()));
}
+
+TEST(LibFuzzerExampleTest, CrashBinary) {
+ char dir_template[] = "/tmp/libfuzzer_example_test_XXXXXX";
+ auto dir = mkdtemp(dir_template);
+ ASSERT_TRUE(dir);
+
+ std::string cmd = "./libfuzzer_bin_example -max_len=150 -artifact_prefix=" +
+ std::string(dir) + "/ " + dir + "/";
+ int retvalue = std::system(cmd.c_str());
+ EXPECT_EQ(kDefaultLibFuzzerError, WSTOPSIG(retvalue));
+
+ // Cleanup.
+ EXPECT_EQ(0, std::system((std::string("rm -rf ") + dir).c_str()));
+}