xref: /aosp_15_r20/external/libprotobuf-mutator/src/mutator.h (revision fd525a9c096e28cf6f8d8719388df0568a611e7b)
1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2016 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 #ifndef SRC_MUTATOR_H_
16*fd525a9cSAndroid Build Coastguard Worker #define SRC_MUTATOR_H_
17*fd525a9cSAndroid Build Coastguard Worker 
18*fd525a9cSAndroid Build Coastguard Worker #include <stddef.h>
19*fd525a9cSAndroid Build Coastguard Worker #include <stdint.h>
20*fd525a9cSAndroid Build Coastguard Worker 
21*fd525a9cSAndroid Build Coastguard Worker #include <functional>
22*fd525a9cSAndroid Build Coastguard Worker #include <memory>
23*fd525a9cSAndroid Build Coastguard Worker #include <random>
24*fd525a9cSAndroid Build Coastguard Worker #include <string>
25*fd525a9cSAndroid Build Coastguard Worker #include <unordered_map>
26*fd525a9cSAndroid Build Coastguard Worker #include <vector>
27*fd525a9cSAndroid Build Coastguard Worker 
28*fd525a9cSAndroid Build Coastguard Worker #include "port/protobuf.h"
29*fd525a9cSAndroid Build Coastguard Worker #include "src/random.h"
30*fd525a9cSAndroid Build Coastguard Worker 
31*fd525a9cSAndroid Build Coastguard Worker namespace protobuf_mutator {
32*fd525a9cSAndroid Build Coastguard Worker 
33*fd525a9cSAndroid Build Coastguard Worker // Randomly makes incremental change in the given protobuf.
34*fd525a9cSAndroid Build Coastguard Worker // Usage example:
35*fd525a9cSAndroid Build Coastguard Worker //    protobuf_mutator::Mutator mutator(1);
36*fd525a9cSAndroid Build Coastguard Worker //    MyMessage message;
37*fd525a9cSAndroid Build Coastguard Worker //    message.ParseFromString(encoded_message);
38*fd525a9cSAndroid Build Coastguard Worker //    mutator.Mutate(&message, 10000);
39*fd525a9cSAndroid Build Coastguard Worker //
40*fd525a9cSAndroid Build Coastguard Worker // Class implements very basic mutations of fields. E.g. it just flips bits for
41*fd525a9cSAndroid Build Coastguard Worker // integers, floats and strings. Also it increases, decreases size of
42*fd525a9cSAndroid Build Coastguard Worker // strings only by one. For better results users should override
43*fd525a9cSAndroid Build Coastguard Worker // protobuf_mutator::Mutator::Mutate* methods with more useful logic, e.g. using
44*fd525a9cSAndroid Build Coastguard Worker // library like libFuzzer.
45*fd525a9cSAndroid Build Coastguard Worker class Mutator {
46*fd525a9cSAndroid Build Coastguard Worker  public:
47*fd525a9cSAndroid Build Coastguard Worker   // seed: value to initialize random number generator.
48*fd525a9cSAndroid Build Coastguard Worker   Mutator() = default;
49*fd525a9cSAndroid Build Coastguard Worker   virtual ~Mutator() = default;
50*fd525a9cSAndroid Build Coastguard Worker 
51*fd525a9cSAndroid Build Coastguard Worker   // Initialized internal random number generator.
52*fd525a9cSAndroid Build Coastguard Worker   void Seed(uint32_t value);
53*fd525a9cSAndroid Build Coastguard Worker 
54*fd525a9cSAndroid Build Coastguard Worker   // message: message to mutate.
55*fd525a9cSAndroid Build Coastguard Worker   // max_size_hint: approximate max ByteSize() of resulting message. Method does
56*fd525a9cSAndroid Build Coastguard Worker   // not guarantee that real result will be strictly smaller than value. Caller
57*fd525a9cSAndroid Build Coastguard Worker   // could repeat mutation if result was larger than expected.
58*fd525a9cSAndroid Build Coastguard Worker   void Mutate(protobuf::Message* message, size_t max_size_hint);
59*fd525a9cSAndroid Build Coastguard Worker 
60*fd525a9cSAndroid Build Coastguard Worker   void CrossOver(const protobuf::Message& message1, protobuf::Message* message2,
61*fd525a9cSAndroid Build Coastguard Worker                  size_t max_size_hint);
62*fd525a9cSAndroid Build Coastguard Worker 
63*fd525a9cSAndroid Build Coastguard Worker   // Makes message initialized and calls post processors to make it valid.
64*fd525a9cSAndroid Build Coastguard Worker   void Fix(protobuf::Message* message);
65*fd525a9cSAndroid Build Coastguard Worker 
66*fd525a9cSAndroid Build Coastguard Worker   // Callback to postprocess mutations.
67*fd525a9cSAndroid Build Coastguard Worker   // Implementation should use seed to initialize random number generators.
68*fd525a9cSAndroid Build Coastguard Worker   using PostProcess =
69*fd525a9cSAndroid Build Coastguard Worker       std::function<void(protobuf::Message* message, unsigned int seed)>;
70*fd525a9cSAndroid Build Coastguard Worker 
71*fd525a9cSAndroid Build Coastguard Worker   // Register callback which will be called after every message mutation.
72*fd525a9cSAndroid Build Coastguard Worker   // In this callback fuzzer may adjust content of the message or mutate some
73*fd525a9cSAndroid Build Coastguard Worker   // fields in some fuzzer specific way.
74*fd525a9cSAndroid Build Coastguard Worker   void RegisterPostProcessor(const protobuf::Descriptor* desc,
75*fd525a9cSAndroid Build Coastguard Worker                              PostProcess callback);
76*fd525a9cSAndroid Build Coastguard Worker 
77*fd525a9cSAndroid Build Coastguard Worker  protected:
78*fd525a9cSAndroid Build Coastguard Worker   // TODO(vitalybuka): Consider to replace with single mutate (uint8_t*, size).
79*fd525a9cSAndroid Build Coastguard Worker   virtual int32_t MutateInt32(int32_t value);
80*fd525a9cSAndroid Build Coastguard Worker   virtual int64_t MutateInt64(int64_t value);
81*fd525a9cSAndroid Build Coastguard Worker   virtual uint32_t MutateUInt32(uint32_t value);
82*fd525a9cSAndroid Build Coastguard Worker   virtual uint64_t MutateUInt64(uint64_t value);
83*fd525a9cSAndroid Build Coastguard Worker   virtual float MutateFloat(float value);
84*fd525a9cSAndroid Build Coastguard Worker   virtual double MutateDouble(double value);
85*fd525a9cSAndroid Build Coastguard Worker   virtual bool MutateBool(bool value);
86*fd525a9cSAndroid Build Coastguard Worker   virtual size_t MutateEnum(size_t index, size_t item_count);
87*fd525a9cSAndroid Build Coastguard Worker   virtual std::string MutateString(const std::string& value,
88*fd525a9cSAndroid Build Coastguard Worker                                    int size_increase_hint);
89*fd525a9cSAndroid Build Coastguard Worker 
random()90*fd525a9cSAndroid Build Coastguard Worker   RandomEngine* random() { return &random_; }
91*fd525a9cSAndroid Build Coastguard Worker 
92*fd525a9cSAndroid Build Coastguard Worker  private:
93*fd525a9cSAndroid Build Coastguard Worker   friend class FieldMutator;
94*fd525a9cSAndroid Build Coastguard Worker   friend class TestMutator;
95*fd525a9cSAndroid Build Coastguard Worker   bool MutateImpl(const std::vector<const protobuf::Message*>& sources,
96*fd525a9cSAndroid Build Coastguard Worker                   const std::vector<protobuf::Message*>& messages,
97*fd525a9cSAndroid Build Coastguard Worker                   bool copy_clone_only, int size_increase_hint);
98*fd525a9cSAndroid Build Coastguard Worker   std::string MutateUtf8String(const std::string& value,
99*fd525a9cSAndroid Build Coastguard Worker                                int size_increase_hint);
100*fd525a9cSAndroid Build Coastguard Worker   bool IsInitialized(const protobuf::Message& message) const;
101*fd525a9cSAndroid Build Coastguard Worker   bool keep_initialized_ = true;
102*fd525a9cSAndroid Build Coastguard Worker   size_t random_to_default_ratio_ = 100;
103*fd525a9cSAndroid Build Coastguard Worker   RandomEngine random_;
104*fd525a9cSAndroid Build Coastguard Worker   using PostProcessors =
105*fd525a9cSAndroid Build Coastguard Worker       std::unordered_multimap<const protobuf::Descriptor*, PostProcess>;
106*fd525a9cSAndroid Build Coastguard Worker   PostProcessors post_processors_;
107*fd525a9cSAndroid Build Coastguard Worker };
108*fd525a9cSAndroid Build Coastguard Worker 
109*fd525a9cSAndroid Build Coastguard Worker }  // namespace protobuf_mutator
110*fd525a9cSAndroid Build Coastguard Worker 
111*fd525a9cSAndroid Build Coastguard Worker #endif  // SRC_MUTATOR_H_
112