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