1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2017 Google Inc. All rights reserved.
2*fd525a9cSAndroid Build Coastguard Worker //
3*fd525a9cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*fd525a9cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*fd525a9cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*fd525a9cSAndroid Build Coastguard Worker //
7*fd525a9cSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*fd525a9cSAndroid Build Coastguard Worker //
9*fd525a9cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*fd525a9cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*fd525a9cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*fd525a9cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*fd525a9cSAndroid Build Coastguard Worker // limitations under the License.
14*fd525a9cSAndroid Build Coastguard Worker
15*fd525a9cSAndroid Build Coastguard Worker #include <cmath>
16*fd525a9cSAndroid Build Coastguard Worker #include <iostream>
17*fd525a9cSAndroid Build Coastguard Worker
18*fd525a9cSAndroid Build Coastguard Worker #include "examples/libfuzzer/libfuzzer_example.pb.h"
19*fd525a9cSAndroid Build Coastguard Worker #include "port/protobuf.h"
20*fd525a9cSAndroid Build Coastguard Worker #include "src/libfuzzer/libfuzzer_macro.h"
21*fd525a9cSAndroid Build Coastguard Worker
22*fd525a9cSAndroid Build Coastguard Worker protobuf_mutator::protobuf::LogSilencer log_silincer;
23*fd525a9cSAndroid Build Coastguard Worker
24*fd525a9cSAndroid Build Coastguard Worker template <class Proto>
25*fd525a9cSAndroid Build Coastguard Worker using PostProcessor =
26*fd525a9cSAndroid Build Coastguard Worker protobuf_mutator::libfuzzer::PostProcessorRegistration<Proto>;
27*fd525a9cSAndroid Build Coastguard Worker
28*fd525a9cSAndroid Build Coastguard Worker static PostProcessor<libfuzzer_example::Msg> reg1 = {
__anon9333d74d0102() 29*fd525a9cSAndroid Build Coastguard Worker [](libfuzzer_example::Msg* message, unsigned int seed) {
30*fd525a9cSAndroid Build Coastguard Worker message->set_optional_uint64(
31*fd525a9cSAndroid Build Coastguard Worker std::hash<std::string>{}(message->optional_string()));
32*fd525a9cSAndroid Build Coastguard Worker }};
33*fd525a9cSAndroid Build Coastguard Worker
34*fd525a9cSAndroid Build Coastguard Worker static PostProcessor<google::protobuf::Any> reg2 = {
__anon9333d74d0202() 35*fd525a9cSAndroid Build Coastguard Worker [](google::protobuf::Any* any, unsigned int seed) {
36*fd525a9cSAndroid Build Coastguard Worker // Guide mutator to usefull 'Any' types.
37*fd525a9cSAndroid Build Coastguard Worker static const char* const expected_types[] = {
38*fd525a9cSAndroid Build Coastguard Worker "type.googleapis.com/google.protobuf.DescriptorProto",
39*fd525a9cSAndroid Build Coastguard Worker "type.googleapis.com/google.protobuf.FileDescriptorProto",
40*fd525a9cSAndroid Build Coastguard Worker };
41*fd525a9cSAndroid Build Coastguard Worker
42*fd525a9cSAndroid Build Coastguard Worker if (!std::count(std::begin(expected_types), std::end(expected_types),
43*fd525a9cSAndroid Build Coastguard Worker any->type_url())) {
44*fd525a9cSAndroid Build Coastguard Worker const size_t num =
45*fd525a9cSAndroid Build Coastguard Worker (std::end(expected_types) - std::begin(expected_types));
46*fd525a9cSAndroid Build Coastguard Worker any->set_type_url(expected_types[seed % num]);
47*fd525a9cSAndroid Build Coastguard Worker }
48*fd525a9cSAndroid Build Coastguard Worker }};
49*fd525a9cSAndroid Build Coastguard Worker
DEFINE_PROTO_FUZZER(const libfuzzer_example::Msg & message)50*fd525a9cSAndroid Build Coastguard Worker DEFINE_PROTO_FUZZER(const libfuzzer_example::Msg& message) {
51*fd525a9cSAndroid Build Coastguard Worker protobuf_mutator::protobuf::FileDescriptorProto file;
52*fd525a9cSAndroid Build Coastguard Worker
53*fd525a9cSAndroid Build Coastguard Worker // Emulate a bug.
54*fd525a9cSAndroid Build Coastguard Worker if (message.optional_uint64() ==
55*fd525a9cSAndroid Build Coastguard Worker std::hash<std::string>{}(message.optional_string()) &&
56*fd525a9cSAndroid Build Coastguard Worker message.optional_string() == "abcdefghijklmnopqrstuvwxyz" &&
57*fd525a9cSAndroid Build Coastguard Worker !std::isnan(message.optional_float()) &&
58*fd525a9cSAndroid Build Coastguard Worker std::fabs(message.optional_float()) > 1000 &&
59*fd525a9cSAndroid Build Coastguard Worker message.any().UnpackTo(&file) && !file.name().empty()) {
60*fd525a9cSAndroid Build Coastguard Worker std::cerr << message.DebugString() << "\n";
61*fd525a9cSAndroid Build Coastguard Worker abort();
62*fd525a9cSAndroid Build Coastguard Worker }
63*fd525a9cSAndroid Build Coastguard Worker }
64