• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include "examples/libfuzzer/libfuzzer_example.pb.h"
18 #include "port/protobuf.h"
19 #include "src/libfuzzer/libfuzzer_macro.h"
20 
21 protobuf_mutator::protobuf::LogSilencer log_silincer;
22 
DEFINE_PROTO_FUZZER(const libfuzzer_example::Msg & message)23 DEFINE_PROTO_FUZZER(const libfuzzer_example::Msg& message) {
24   static PostProcessorRegistration reg = {
25       [](libfuzzer_example::Msg* message, unsigned int seed) {
26         if (seed % 2) {
27           message->set_optional_uint64(
28               std::hash<std::string>{}(message->optional_string()));
29         }
30 
31         if (message->has_any()) {
32           auto* any = message->mutable_any();
33 
34           // Guide mutator to usefull 'Any' types.
35           static const char* const expected_types[] = {
36               "type.googleapis.com/google.protobuf.DescriptorProto",
37               "type.googleapis.com/google.protobuf.FileDescriptorProto",
38           };
39 
40           if (!std::count(std::begin(expected_types), std::end(expected_types),
41                           any->type_url())) {
42             const size_t num =
43                 (std::end(expected_types) - std::begin(expected_types));
44             any->set_type_url(expected_types[seed % num]);
45           }
46         }
47       }};
48 
49   protobuf_mutator::protobuf::FileDescriptorProto file;
50 
51   // Emulate a bug.
52   if (message.optional_uint64() ==
53           std::hash<std::string>{}(message.optional_string()) &&
54       message.optional_string() == "abcdefghijklmnopqrstuvwxyz" &&
55       !std::isnan(message.optional_float()) &&
56       std::fabs(message.optional_float()) > 1000 &&
57       message.any().UnpackTo(&file) && !file.name().empty()) {
58     std::cerr << message.DebugString() << "\n";
59     abort();
60   }
61 }
62