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