xref: /aosp_15_r20/external/libprotobuf-mutator/examples/libfuzzer/libfuzzer_example.cc (revision fd525a9c096e28cf6f8d8719388df0568a611e7b)
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