Coverage Report

Created: 2025-12-10 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libprotobuf-mutator/src/mutator.cc
Line
Count
Source
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
#include "src/mutator.h"
16
17
#include <algorithm>
18
#include <bitset>
19
#include <iostream>
20
#include <map>
21
#include <memory>
22
#include <random>
23
#include <string>
24
#include <utility>
25
#include <vector>
26
27
#include "src/field_instance.h"
28
#include "src/utf8_fix.h"
29
#include "src/weighted_reservoir_sampler.h"
30
31
namespace protobuf_mutator {
32
33
using google::protobuf::Any;
34
using protobuf::Descriptor;
35
using protobuf::FieldDescriptor;
36
using protobuf::FileDescriptor;
37
using protobuf::Message;
38
using protobuf::OneofDescriptor;
39
using protobuf::Reflection;
40
using protobuf::util::MessageDifferencer;
41
using std::placeholders::_1;
42
43
namespace {
44
45
const int kMaxInitializeDepth = 200;
46
const uint64_t kDefaultMutateWeight = 1000000;
47
48
enum class Mutation : uint8_t {
49
  None,
50
  Add,     // Adds new field with default value.
51
  Mutate,  // Mutates field contents.
52
  Delete,  // Deletes field.
53
  Copy,    // Copy values copied from another field.
54
  Clone,   // Create new field with value copied from another.
55
56
  Last = Clone,
57
};
58
59
using MutationBitset = std::bitset<static_cast<size_t>(Mutation::Last) + 1>;
60
61
using Messages = std::vector<Message*>;
62
using ConstMessages = std::vector<const Message*>;
63
64
// Return random integer from [0, count)
65
0
size_t GetRandomIndex(RandomEngine* random, size_t count) {
66
0
  assert(count > 0);
67
0
  if (count == 1) return 0;
68
0
  return std::uniform_int_distribution<size_t>(0, count - 1)(*random);
69
0
}
70
71
// Flips random bit in the buffer.
72
0
void FlipBit(size_t size, uint8_t* bytes, RandomEngine* random) {
73
0
  size_t bit = GetRandomIndex(random, size * 8);
74
0
  bytes[bit / 8] ^= (1u << (bit % 8));
75
0
}
76
77
// Flips random bit in the value.
78
template <class T>
79
0
T FlipBit(T value, RandomEngine* random) {
80
0
  FlipBit(sizeof(value), reinterpret_cast<uint8_t*>(&value), random);
81
0
  return value;
82
0
}
Unexecuted instantiation: mutator.cc:int protobuf_mutator::(anonymous namespace)::FlipBit<int>(int, std::__1::linear_congruential_engine<unsigned long, 48271ul, 0ul, 2147483647ul>*)
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::FlipBit<long>(long, std::__1::linear_congruential_engine<unsigned long, 48271ul, 0ul, 2147483647ul>*)
Unexecuted instantiation: mutator.cc:unsigned int protobuf_mutator::(anonymous namespace)::FlipBit<unsigned int>(unsigned int, std::__1::linear_congruential_engine<unsigned long, 48271ul, 0ul, 2147483647ul>*)
Unexecuted instantiation: mutator.cc:unsigned long protobuf_mutator::(anonymous namespace)::FlipBit<unsigned long>(unsigned long, std::__1::linear_congruential_engine<unsigned long, 48271ul, 0ul, 2147483647ul>*)
Unexecuted instantiation: mutator.cc:float protobuf_mutator::(anonymous namespace)::FlipBit<float>(float, std::__1::linear_congruential_engine<unsigned long, 48271ul, 0ul, 2147483647ul>*)
Unexecuted instantiation: mutator.cc:double protobuf_mutator::(anonymous namespace)::FlipBit<double>(double, std::__1::linear_congruential_engine<unsigned long, 48271ul, 0ul, 2147483647ul>*)
83
84
// Return true with probability about 1-of-n.
85
0
bool GetRandomBool(RandomEngine* random, size_t n = 2) {
86
0
  return GetRandomIndex(random, n) == 0;
87
0
}
88
89
0
bool IsProto3SimpleField(const FieldDescriptor& field) {
90
0
  assert(field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
91
0
         field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2);
92
0
  return field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
93
0
         field.cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
94
0
         !field.containing_oneof() && !field.is_repeated();
95
0
}
96
97
struct CreateDefaultField : public FieldFunction<CreateDefaultField> {
98
  template <class T>
99
3.68k
  void ForType(const FieldInstance& field) const {
100
3.68k
    T value;
101
3.68k
    field.GetDefault(&value);
102
3.68k
    field.Create(value);
103
3.68k
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<int>(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
27
  void ForType(const FieldInstance& field) const {
100
27
    T value;
101
27
    field.GetDefault(&value);
102
27
    field.Create(value);
103
27
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<long>(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
309
  void ForType(const FieldInstance& field) const {
100
309
    T value;
101
309
    field.GetDefault(&value);
102
309
    field.Create(value);
103
309
  }
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<unsigned int>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<unsigned long>(protobuf_mutator::FieldInstance const&) const
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<double>(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
12
  void ForType(const FieldInstance& field) const {
100
12
    T value;
101
12
    field.GetDefault(&value);
102
12
    field.Create(value);
103
12
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<float>(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
9
  void ForType(const FieldInstance& field) const {
100
9
    T value;
101
9
    field.GetDefault(&value);
102
9
    field.Create(value);
103
9
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<bool>(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
457
  void ForType(const FieldInstance& field) const {
100
457
    T value;
101
457
    field.GetDefault(&value);
102
457
    field.Create(value);
103
457
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
1.48k
  void ForType(const FieldInstance& field) const {
100
1.48k
    T value;
101
1.48k
    field.GetDefault(&value);
102
1.48k
    field.Create(value);
103
1.48k
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
135
  void ForType(const FieldInstance& field) const {
100
135
    T value;
101
135
    field.GetDefault(&value);
102
135
    field.Create(value);
103
135
  }
mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<std::__1::unique_ptr<google::protobuf::Message, std::__1::default_delete<google::protobuf::Message> > >(protobuf_mutator::FieldInstance const&) const
Line
Count
Source
99
1.24k
  void ForType(const FieldInstance& field) const {
100
1.24k
    T value;
101
1.24k
    field.GetDefault(&value);
102
1.24k
    field.Create(value);
103
1.24k
  }
104
};
105
106
struct DeleteField : public FieldFunction<DeleteField> {
107
  template <class T>
108
0
  void ForType(const FieldInstance& field) const {
109
0
    field.Delete();
110
0
  }
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<int>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<long>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<unsigned int>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<unsigned long>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<double>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<float>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<bool>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::DeleteField::ForType<std::__1::unique_ptr<google::protobuf::Message, std::__1::default_delete<google::protobuf::Message> > >(protobuf_mutator::FieldInstance const&) const
111
};
112
113
struct CopyField : public FieldFunction<CopyField> {
114
  template <class T>
115
  void ForType(const ConstFieldInstance& source,
116
0
               const FieldInstance& field) const {
117
0
    T value;
118
0
    source.Load(&value);
119
0
    field.Store(value);
120
0
  }
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<int>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<long>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<unsigned int>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<unsigned long>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<double>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<float>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<bool>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CopyField::ForType<std::__1::unique_ptr<google::protobuf::Message, std::__1::default_delete<google::protobuf::Message> > >(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::FieldInstance const&) const
121
};
122
123
struct AppendField : public FieldFunction<AppendField> {
124
  template <class T>
125
  void ForType(const ConstFieldInstance& source,
126
               const FieldInstance& field) const {
127
    T value;
128
    source.Load(&value);
129
    field.Create(value);
130
  }
131
};
132
133
class CanCopyAndDifferentField
134
    : public FieldFunction<CanCopyAndDifferentField, bool> {
135
 public:
136
  template <class T>
137
  bool ForType(const ConstFieldInstance& src, const ConstFieldInstance& dst,
138
0
               int size_increase_hint) const {
139
0
    T s;
140
0
    src.Load(&s);
141
0
    if (!dst.CanStore(s)) return false;
142
0
    T d;
143
0
    dst.Load(&d);
144
0
    return SizeDiff(s, d) <= size_increase_hint && !IsEqual(s, d);
145
0
  }
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<int>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<long>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<unsigned int>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<unsigned long>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<double>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<float>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<bool>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::ForType<std::__1::unique_ptr<google::protobuf::Message, std::__1::default_delete<google::protobuf::Message> > >(protobuf_mutator::ConstFieldInstance const&, protobuf_mutator::ConstFieldInstance const&, int) const
146
147
 private:
148
  bool IsEqual(const ConstFieldInstance::Enum& a,
149
0
               const ConstFieldInstance::Enum& b) const {
150
0
    assert(a.count == b.count);
151
0
    return a.index == b.index;
152
0
  }
153
154
  bool IsEqual(const std::unique_ptr<Message>& a,
155
0
               const std::unique_ptr<Message>& b) const {
156
0
    return MessageDifferencer::Equals(*a, *b);
157
0
  }
158
159
  template <class T>
160
0
  bool IsEqual(const T& a, const T& b) const {
161
0
    return a == b;
162
0
  }
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<int>(int const&, int const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<long>(long const&, long const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<unsigned int>(unsigned int const&, unsigned int const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<unsigned long>(unsigned long const&, unsigned long const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<double>(double const&, double const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<float>(float const&, float const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<bool>(bool const&, bool const&) const
Unexecuted instantiation: mutator.cc:bool protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::IsEqual<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const
163
164
  int64_t SizeDiff(const std::unique_ptr<Message>& src,
165
0
                   const std::unique_ptr<Message>& dst) const {
166
0
    return src->ByteSizeLong() - dst->ByteSizeLong();
167
0
  }
168
169
0
  int64_t SizeDiff(const std::string& src, const std::string& dst) const {
170
0
    return src.size() - dst.size();
171
0
  }
172
173
  template <class T>
174
0
  int64_t SizeDiff(const T&, const T&) const {
175
0
    return 0;
176
0
  }
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<int>(int const&, int const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<long>(long const&, long const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<unsigned int>(unsigned int const&, unsigned int const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<unsigned long>(unsigned long const&, unsigned long const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<double>(double const&, double const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<float>(float const&, float const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<bool>(bool const&, bool const&) const
Unexecuted instantiation: mutator.cc:long protobuf_mutator::(anonymous namespace)::CanCopyAndDifferentField::SizeDiff<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::ConstFieldInstance::Enum const&, protobuf_mutator::ConstFieldInstance::Enum const&) const
177
};
178
179
// Selects random field and mutation from the given proto message.
180
class MutationSampler {
181
 public:
182
  MutationSampler(bool keep_initialized, MutationBitset allowed_mutations,
183
                  RandomEngine* random)
184
0
      : keep_initialized_(keep_initialized),
185
0
        allowed_mutations_(allowed_mutations),
186
0
        random_(random),
187
0
        sampler_(random) {}
188
189
  // Returns selected field.
190
0
  const FieldInstance& field() const { return sampler_.selected().field; }
191
192
  // Returns selected mutation.
193
0
  Mutation mutation() const { return sampler_.selected().mutation; }
194
195
0
  void Sample(Message* message) {
196
0
    SampleImpl(message);
197
0
    assert(mutation() != Mutation::None ||
198
0
           !allowed_mutations_[static_cast<size_t>(Mutation::Mutate)] ||
199
0
           message->GetDescriptor()->field_count() == 0);
200
0
  }
201
202
 private:
203
0
  void SampleImpl(Message* message) {
204
0
    const Descriptor* descriptor = message->GetDescriptor();
205
0
    const Reflection* reflection = message->GetReflection();
206
207
0
    int field_count = descriptor->field_count();
208
0
    for (int i = 0; i < field_count; ++i) {
209
0
      const FieldDescriptor* field = descriptor->field(i);
210
0
      if (const OneofDescriptor* oneof = field->containing_oneof()) {
211
        // Handle entire oneof group on the first field.
212
0
        if (field->index_in_oneof() == 0) {
213
0
          assert(oneof->field_count());
214
0
          const FieldDescriptor* current_field =
215
0
              reflection->GetOneofFieldDescriptor(*message, oneof);
216
0
          for (;;) {
217
0
            const FieldDescriptor* add_field =
218
0
                oneof->field(GetRandomIndex(random_, oneof->field_count()));
219
0
            if (add_field != current_field) {
220
0
              Try({message, add_field}, Mutation::Add);
221
0
              Try({message, add_field}, Mutation::Clone);
222
0
              break;
223
0
            }
224
0
            if (oneof->field_count() < 2) break;
225
0
          }
226
0
          if (current_field) {
227
0
            if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
228
0
              Try({message, current_field}, Mutation::Mutate);
229
0
            Try({message, current_field}, Mutation::Delete);
230
0
            Try({message, current_field}, Mutation::Copy);
231
0
          }
232
0
        }
233
0
      } else {
234
0
        if (field->is_repeated()) {
235
0
          int field_size = reflection->FieldSize(*message, field);
236
0
          size_t random_index = GetRandomIndex(random_, field_size + 1);
237
0
          Try({message, field, random_index}, Mutation::Add);
238
0
          Try({message, field, random_index}, Mutation::Clone);
239
240
0
          if (field_size) {
241
0
            size_t random_index = GetRandomIndex(random_, field_size);
242
0
            if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
243
0
              Try({message, field, random_index}, Mutation::Mutate);
244
0
            Try({message, field, random_index}, Mutation::Delete);
245
0
            Try({message, field, random_index}, Mutation::Copy);
246
0
          }
247
0
        } else {
248
0
          if (reflection->HasField(*message, field) ||
249
0
              IsProto3SimpleField(*field)) {
250
0
            if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
251
0
              Try({message, field}, Mutation::Mutate);
252
0
            if (!IsProto3SimpleField(*field) &&
253
0
                (!field->is_required() || !keep_initialized_)) {
254
0
              Try({message, field}, Mutation::Delete);
255
0
            }
256
0
            Try({message, field}, Mutation::Copy);
257
0
          } else {
258
0
            Try({message, field}, Mutation::Add);
259
0
            Try({message, field}, Mutation::Clone);
260
0
          }
261
0
        }
262
0
      }
263
264
0
      if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
265
0
        if (field->is_repeated()) {
266
0
          const int field_size = reflection->FieldSize(*message, field);
267
0
          for (int j = 0; j < field_size; ++j)
268
0
            SampleImpl(reflection->MutableRepeatedMessage(message, field, j));
269
0
        } else if (reflection->HasField(*message, field)) {
270
0
          SampleImpl(reflection->MutableMessage(message, field));
271
0
        }
272
0
      }
273
0
    }
274
0
  }
275
276
0
  void Try(const FieldInstance& field, Mutation mutation) {
277
0
    assert(mutation != Mutation::None);
278
0
    if (!allowed_mutations_[static_cast<size_t>(mutation)]) return;
279
0
    sampler_.Try(kDefaultMutateWeight, {field, mutation});
280
0
  }
281
282
  bool keep_initialized_ = false;
283
  MutationBitset allowed_mutations_;
284
285
  RandomEngine* random_;
286
287
  struct Result {
288
0
    Result() = default;
289
0
    Result(const FieldInstance& f, Mutation m) : field(f), mutation(m) {}
290
291
    FieldInstance field;
292
    Mutation mutation = Mutation::None;
293
  };
294
  WeightedReservoirSampler<Result, RandomEngine> sampler_;
295
};
296
297
// Selects random field of compatible type to use for clone mutations.
298
class DataSourceSampler {
299
 public:
300
  DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random,
301
                    int size_increase_hint)
302
0
      : match_(match),
303
0
        random_(random),
304
0
        size_increase_hint_(size_increase_hint),
305
0
        sampler_(random) {}
306
307
0
  void Sample(const Message& message) { SampleImpl(message); }
308
309
  // Returns selected field.
310
0
  const ConstFieldInstance& field() const {
311
0
    assert(!IsEmpty());
312
0
    return sampler_.selected();
313
0
  }
314
315
0
  bool IsEmpty() const { return sampler_.IsEmpty(); }
316
317
 private:
318
0
  void SampleImpl(const Message& message) {
319
0
    const Descriptor* descriptor = message.GetDescriptor();
320
0
    const Reflection* reflection = message.GetReflection();
321
322
0
    int field_count = descriptor->field_count();
323
0
    for (int i = 0; i < field_count; ++i) {
324
0
      const FieldDescriptor* field = descriptor->field(i);
325
0
      if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
326
0
        if (field->is_repeated()) {
327
0
          const int field_size = reflection->FieldSize(message, field);
328
0
          for (int j = 0; j < field_size; ++j) {
329
0
            SampleImpl(reflection->GetRepeatedMessage(message, field, j));
330
0
          }
331
0
        } else if (reflection->HasField(message, field)) {
332
0
          SampleImpl(reflection->GetMessage(message, field));
333
0
        }
334
0
      }
335
336
0
      if (field->cpp_type() != match_.cpp_type()) continue;
337
0
      if (match_.cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
338
0
        if (field->enum_type() != match_.enum_type()) continue;
339
0
      } else if (match_.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
340
0
        if (field->message_type() != match_.message_type()) continue;
341
0
      }
342
343
0
      if (field->is_repeated()) {
344
0
        if (int field_size = reflection->FieldSize(message, field)) {
345
0
          ConstFieldInstance source(&message, field,
346
0
                                    GetRandomIndex(random_, field_size));
347
0
          if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
348
0
            sampler_.Try(field_size, source);
349
0
        }
350
0
      } else {
351
0
        if (reflection->HasField(message, field)) {
352
0
          ConstFieldInstance source(&message, field);
353
0
          if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
354
0
            sampler_.Try(1, source);
355
0
        }
356
0
      }
357
0
    }
358
0
  }
359
360
  ConstFieldInstance match_;
361
  RandomEngine* random_;
362
  int size_increase_hint_;
363
364
  WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_;
365
};
366
367
using UnpackedAny =
368
    std::unordered_map<const Message*, std::unique_ptr<Message>>;
369
370
0
const Descriptor* GetAnyTypeDescriptor(const Any& any) {
371
0
  std::string type_name;
372
0
  if (!Any::ParseAnyTypeUrl(std::string(any.type_url()), &type_name))
373
0
    return nullptr;
374
0
  return any.descriptor()->file()->pool()->FindMessageTypeByName(type_name);
375
0
}
376
377
0
std::unique_ptr<Message> UnpackAny(const Any& any) {
378
0
  const Descriptor* desc = GetAnyTypeDescriptor(any);
379
0
  if (!desc) return {};
380
0
  std::unique_ptr<Message> message(
381
0
      any.GetReflection()->GetMessageFactory()->GetPrototype(desc)->New());
382
0
  message->ParsePartialFromString(std::string(any.value()));
383
0
  return message;
384
0
}
385
386
29.9k
const Any* CastToAny(const Message* message) {
387
29.9k
  return Any::GetDescriptor() == message->GetDescriptor()
388
29.9k
             ? static_cast<const Any*>(message)
389
29.9k
             : nullptr;
390
29.9k
}
391
392
31.2k
Any* CastToAny(Message* message) {
393
31.2k
  return Any::GetDescriptor() == message->GetDescriptor()
394
31.2k
             ? static_cast<Any*>(message)
395
31.2k
             : nullptr;
396
31.2k
}
397
398
29.9k
std::unique_ptr<Message> UnpackIfAny(const Message& message) {
399
29.9k
  if (const Any* any = CastToAny(&message)) return UnpackAny(*any);
400
29.9k
  return {};
401
29.9k
}
402
403
29.9k
void UnpackAny(const Message& message, UnpackedAny* result) {
404
29.9k
  if (std::unique_ptr<Message> any = UnpackIfAny(message)) {
405
0
    UnpackAny(*any, result);
406
0
    result->emplace(&message, std::move(any));
407
0
    return;
408
0
  }
409
410
29.9k
  const Descriptor* descriptor = message.GetDescriptor();
411
29.9k
  const Reflection* reflection = message.GetReflection();
412
413
142k
  for (int i = 0; i < descriptor->field_count(); ++i) {
414
112k
    const FieldDescriptor* field = descriptor->field(i);
415
112k
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
416
74.8k
      if (field->is_repeated()) {
417
1.45k
        const int field_size = reflection->FieldSize(message, field);
418
8.13k
        for (int j = 0; j < field_size; ++j) {
419
6.68k
          UnpackAny(reflection->GetRepeatedMessage(message, field, j), result);
420
6.68k
        }
421
73.4k
      } else if (reflection->HasField(message, field)) {
422
20.5k
        UnpackAny(reflection->GetMessage(message, field), result);
423
20.5k
      }
424
74.8k
    }
425
112k
  }
426
29.9k
}
427
428
class PostProcessing {
429
 public:
430
  using PostProcessors =
431
      std::unordered_multimap<const Descriptor*, Mutator::PostProcess>;
432
433
  PostProcessing(bool keep_initialized, const PostProcessors& post_processors,
434
                 const UnpackedAny& any, RandomEngine* random)
435
2.77k
      : keep_initialized_(keep_initialized),
436
2.77k
        post_processors_(post_processors),
437
2.77k
        any_(any),
438
2.77k
        random_(random) {}
439
440
31.2k
  void Run(Message* message, int max_depth) {
441
31.2k
    --max_depth;
442
31.2k
    const Descriptor* descriptor = message->GetDescriptor();
443
444
    // Apply custom mutators in nested messages before packing any.
445
31.2k
    const Reflection* reflection = message->GetReflection();
446
148k
    for (int i = 0; i < descriptor->field_count(); i++) {
447
117k
      const FieldDescriptor* field = descriptor->field(i);
448
117k
      if (keep_initialized_ &&
449
117k
          (field->is_required() || descriptor->options().map_entry()) &&
450
49.1k
          !reflection->HasField(*message, field)) {
451
3.68k
        CreateDefaultField()(FieldInstance(message, field));
452
3.68k
      }
453
454
117k
      if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
455
456
77.4k
      if (max_depth < 0 && !field->is_required()) {
457
        // Clear deep optional fields to avoid stack overflow.
458
0
        reflection->ClearField(message, field);
459
0
        if (field->is_repeated())
460
0
          assert(!reflection->FieldSize(*message, field));
461
0
        else
462
0
          assert(!reflection->HasField(*message, field));
463
0
        continue;
464
0
      }
465
466
77.4k
      if (field->is_repeated()) {
467
1.45k
        const int field_size = reflection->FieldSize(*message, field);
468
8.13k
        for (int j = 0; j < field_size; ++j) {
469
6.68k
          Message* nested_message =
470
6.68k
              reflection->MutableRepeatedMessage(message, field, j);
471
6.68k
          Run(nested_message, max_depth);
472
6.68k
        }
473
75.9k
      } else if (reflection->HasField(*message, field)) {
474
21.7k
        Message* nested_message = reflection->MutableMessage(message, field);
475
21.7k
        Run(nested_message, max_depth);
476
21.7k
      }
477
77.4k
    }
478
479
31.2k
    if (Any* any = CastToAny(message)) {
480
0
      if (max_depth < 0) {
481
        // Clear deep Any fields to avoid stack overflow.
482
0
        any->Clear();
483
0
      } else {
484
0
        auto It = any_.find(message);
485
0
        if (It != any_.end()) {
486
0
          Run(It->second.get(), max_depth);
487
0
          std::string value;
488
0
          It->second->SerializePartialToString(&value);
489
0
          *any->mutable_value() = value;
490
0
        }
491
0
      }
492
0
    }
493
494
    // Call user callback after message trimmed, initialized and packed.
495
31.2k
    auto range = post_processors_.equal_range(descriptor);
496
31.2k
    for (auto it = range.first; it != range.second; ++it)
497
0
      it->second(message, (*random_)());
498
31.2k
  }
499
500
 private:
501
  bool keep_initialized_;
502
  const PostProcessors& post_processors_;
503
  const UnpackedAny& any_;
504
  RandomEngine* random_;
505
};
506
507
}  // namespace
508
509
class FieldMutator {
510
 public:
511
  FieldMutator(int size_increase_hint, bool enforce_changes,
512
               bool enforce_utf8_strings, const ConstMessages& sources,
513
               Mutator* mutator)
514
0
      : size_increase_hint_(size_increase_hint),
515
0
        enforce_changes_(enforce_changes),
516
0
        enforce_utf8_strings_(enforce_utf8_strings),
517
0
        sources_(sources),
518
0
        mutator_(mutator) {}
519
520
0
  void Mutate(int32_t* value) const {
521
0
    RepeatMutate(value, std::bind(&Mutator::MutateInt32, mutator_, _1));
522
0
  }
523
524
0
  void Mutate(int64_t* value) const {
525
0
    RepeatMutate(value, std::bind(&Mutator::MutateInt64, mutator_, _1));
526
0
  }
527
528
0
  void Mutate(uint32_t* value) const {
529
0
    RepeatMutate(value, std::bind(&Mutator::MutateUInt32, mutator_, _1));
530
0
  }
531
532
0
  void Mutate(uint64_t* value) const {
533
0
    RepeatMutate(value, std::bind(&Mutator::MutateUInt64, mutator_, _1));
534
0
  }
535
536
0
  void Mutate(float* value) const {
537
0
    RepeatMutate(value, std::bind(&Mutator::MutateFloat, mutator_, _1));
538
0
  }
539
540
0
  void Mutate(double* value) const {
541
0
    RepeatMutate(value, std::bind(&Mutator::MutateDouble, mutator_, _1));
542
0
  }
543
544
0
  void Mutate(bool* value) const {
545
0
    RepeatMutate(value, std::bind(&Mutator::MutateBool, mutator_, _1));
546
0
  }
547
548
0
  void Mutate(FieldInstance::Enum* value) const {
549
0
    RepeatMutate(&value->index,
550
0
                 std::bind(&Mutator::MutateEnum, mutator_, _1, value->count));
551
0
    assert(value->index < value->count);
552
0
  }
553
554
0
  void Mutate(std::string* value) const {
555
0
    if (enforce_utf8_strings_) {
556
0
      RepeatMutate(value, std::bind(&Mutator::MutateUtf8String, mutator_, _1,
557
0
                                    size_increase_hint_));
558
0
    } else {
559
0
      RepeatMutate(value, std::bind(&Mutator::MutateString, mutator_, _1,
560
0
                                    size_increase_hint_));
561
0
    }
562
0
  }
563
564
0
  void Mutate(std::unique_ptr<Message>* message) const {
565
0
    assert(!enforce_changes_);
566
0
    assert(*message);
567
0
    if (GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_))
568
0
      return;
569
0
    mutator_->MutateImpl(sources_, {message->get()}, false,
570
0
                         size_increase_hint_);
571
0
  }
572
573
 private:
574
  template <class T, class F>
575
0
  void RepeatMutate(T* value, F mutate) const {
576
0
    if (!enforce_changes_ &&
577
0
        GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_)) {
578
0
      return;
579
0
    }
580
0
    T tmp = *value;
581
0
    for (int i = 0; i < 10; ++i) {
582
0
      *value = mutate(*value);
583
0
      if (!enforce_changes_ || *value != tmp) return;
584
0
    }
585
0
  }
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<int, std::__1::__bind<int (protobuf_mutator::Mutator::*)(int), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(int*, std::__1::__bind<int (protobuf_mutator::Mutator::*)(int), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<long, std::__1::__bind<long (protobuf_mutator::Mutator::*)(long), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(long*, std::__1::__bind<long (protobuf_mutator::Mutator::*)(long), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<unsigned int, std::__1::__bind<unsigned int (protobuf_mutator::Mutator::*)(unsigned int), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(unsigned int*, std::__1::__bind<unsigned int (protobuf_mutator::Mutator::*)(unsigned int), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<unsigned long, std::__1::__bind<unsigned long (protobuf_mutator::Mutator::*)(unsigned long), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(unsigned long*, std::__1::__bind<unsigned long (protobuf_mutator::Mutator::*)(unsigned long), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<double, std::__1::__bind<double (protobuf_mutator::Mutator::*)(double), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(double*, std::__1::__bind<double (protobuf_mutator::Mutator::*)(double), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<float, std::__1::__bind<float (protobuf_mutator::Mutator::*)(float), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(float*, std::__1::__bind<float (protobuf_mutator::Mutator::*)(float), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<bool, std::__1::__bind<bool (protobuf_mutator::Mutator::*)(bool), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&> >(bool*, std::__1::__bind<bool (protobuf_mutator::Mutator::*)(bool), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<unsigned long, std::__1::__bind<unsigned long (protobuf_mutator::Mutator::*)(unsigned long, unsigned long), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&, unsigned long&> >(unsigned long*, std::__1::__bind<unsigned long (protobuf_mutator::Mutator::*)(unsigned long, unsigned long), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&, unsigned long&>) const
Unexecuted instantiation: void protobuf_mutator::FieldMutator::RepeatMutate<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__bind<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > (protobuf_mutator::Mutator::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&, int const&> >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, std::__1::__bind<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > (protobuf_mutator::Mutator::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int), protobuf_mutator::Mutator* const&, std::__1::placeholders::__ph<1> const&, int const&>) const
586
587
  int size_increase_hint_;
588
  size_t enforce_changes_;
589
  bool enforce_utf8_strings_;
590
  const ConstMessages& sources_;
591
  Mutator* mutator_;
592
};
593
594
namespace {
595
596
struct MutateField : public FieldFunction<MutateField> {
597
  template <class T>
598
  void ForType(const FieldInstance& field, int size_increase_hint,
599
0
               const ConstMessages& sources, Mutator* mutator) const {
600
0
    T value;
601
0
    field.Load(&value);
602
0
    FieldMutator(size_increase_hint, true, field.EnforceUtf8(), sources,
603
0
                 mutator)
604
0
        .Mutate(&value);
605
0
    field.Store(value);
606
0
  }
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<int>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<long>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<unsigned int>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<unsigned long>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<double>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<float>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<bool>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::MutateField::ForType<std::__1::unique_ptr<google::protobuf::Message, std::__1::default_delete<google::protobuf::Message> > >(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
607
};
608
609
struct CreateField : public FieldFunction<CreateField> {
610
 public:
611
  template <class T>
612
  void ForType(const FieldInstance& field, int size_increase_hint,
613
0
               const ConstMessages& sources, Mutator* mutator) const {
614
0
    T value;
615
0
    field.GetDefault(&value);
616
0
    FieldMutator field_mutator(size_increase_hint,
617
0
                               false /* defaults could be useful */,
618
0
                               field.EnforceUtf8(), sources, mutator);
619
0
    field_mutator.Mutate(&value);
620
0
    field.Create(value);
621
0
  }
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<int>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<long>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<unsigned int>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<unsigned long>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<double>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<float>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<bool>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<protobuf_mutator::ConstFieldInstance::Enum>(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
Unexecuted instantiation: mutator.cc:void protobuf_mutator::(anonymous namespace)::CreateField::ForType<std::__1::unique_ptr<google::protobuf::Message, std::__1::default_delete<google::protobuf::Message> > >(protobuf_mutator::FieldInstance const&, int, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*> > const&, protobuf_mutator::Mutator*) const
622
};
623
624
}  // namespace
625
626
2.77k
void Mutator::Seed(uint32_t value) { random_.seed(value); }
627
628
2.77k
void Mutator::Fix(Message* message) {
629
2.77k
  UnpackedAny any;
630
2.77k
  UnpackAny(*message, &any);
631
632
2.77k
  PostProcessing(keep_initialized_, post_processors_, any, &random_)
633
2.77k
      .Run(message, kMaxInitializeDepth);
634
2.77k
  assert(IsInitialized(*message));
635
2.77k
}
636
637
0
void Mutator::Mutate(Message* message, size_t max_size_hint) {
638
0
  UnpackedAny any;
639
0
  UnpackAny(*message, &any);
640
641
0
  Messages messages;
642
0
  messages.reserve(any.size() + 1);
643
0
  messages.push_back(message);
644
0
  for (const auto& kv : any) messages.push_back(kv.second.get());
645
646
0
  ConstMessages sources(messages.begin(), messages.end());
647
0
  MutateImpl(sources, messages, false,
648
0
             static_cast<int>(max_size_hint) -
649
0
                 static_cast<int>(message->ByteSizeLong()));
650
651
0
  PostProcessing(keep_initialized_, post_processors_, any, &random_)
652
0
      .Run(message, kMaxInitializeDepth);
653
0
  assert(IsInitialized(*message));
654
0
}
655
656
void Mutator::CrossOver(const Message& message1, Message* message2,
657
0
                        size_t max_size_hint) {
658
0
  UnpackedAny any;
659
0
  UnpackAny(*message2, &any);
660
661
0
  Messages messages;
662
0
  messages.reserve(any.size() + 1);
663
0
  messages.push_back(message2);
664
0
  for (auto& kv : any) messages.push_back(kv.second.get());
665
666
0
  UnpackAny(message1, &any);
667
668
0
  ConstMessages sources;
669
0
  sources.reserve(any.size() + 2);
670
0
  sources.push_back(&message1);
671
0
  sources.push_back(message2);
672
0
  for (const auto& kv : any) sources.push_back(kv.second.get());
673
674
0
  MutateImpl(sources, messages, true,
675
0
             static_cast<int>(max_size_hint) -
676
0
                 static_cast<int>(message2->ByteSizeLong()));
677
678
0
  PostProcessing(keep_initialized_, post_processors_, any, &random_)
679
0
      .Run(message2, kMaxInitializeDepth);
680
0
  assert(IsInitialized(*message2));
681
0
}
682
683
void Mutator::RegisterPostProcessor(const Descriptor* desc,
684
0
                                    PostProcess callback) {
685
0
  post_processors_.emplace(desc, callback);
686
0
}
687
688
bool Mutator::MutateImpl(const ConstMessages& sources, const Messages& messages,
689
0
                         bool copy_clone_only, int size_increase_hint) {
690
0
  MutationBitset mutations;
691
0
  if (copy_clone_only) {
692
0
    mutations[static_cast<size_t>(Mutation::Copy)] = true;
693
0
    mutations[static_cast<size_t>(Mutation::Clone)] = true;
694
0
  } else if (size_increase_hint <= 16) {
695
0
    mutations[static_cast<size_t>(Mutation::Delete)] = true;
696
0
  } else {
697
0
    mutations.set();
698
0
    mutations[static_cast<size_t>(Mutation::Copy)] = false;
699
0
    mutations[static_cast<size_t>(Mutation::Clone)] = false;
700
0
  }
701
0
  while (mutations.any()) {
702
0
    MutationSampler mutation(keep_initialized_, mutations, &random_);
703
0
    for (Message* message : messages) mutation.Sample(message);
704
705
0
    switch (mutation.mutation()) {
706
0
      case Mutation::None:
707
0
        return true;
708
0
      case Mutation::Add:
709
0
        CreateField()(mutation.field(), size_increase_hint, sources, this);
710
0
        return true;
711
0
      case Mutation::Mutate:
712
0
        MutateField()(mutation.field(), size_increase_hint, sources, this);
713
0
        return true;
714
0
      case Mutation::Delete:
715
0
        DeleteField()(mutation.field());
716
0
        return true;
717
0
      case Mutation::Clone: {
718
0
        CreateDefaultField()(mutation.field());
719
0
        DataSourceSampler source_sampler(mutation.field(), &random_,
720
0
                                         size_increase_hint);
721
0
        for (const Message* source : sources) source_sampler.Sample(*source);
722
0
        if (source_sampler.IsEmpty()) {
723
0
          if (!IsProto3SimpleField(*mutation.field().descriptor()))
724
0
            return true;  // CreateField is enough for proto2.
725
0
          break;
726
0
        }
727
0
        CopyField()(source_sampler.field(), mutation.field());
728
0
        return true;
729
0
      }
730
0
      case Mutation::Copy: {
731
0
        DataSourceSampler source_sampler(mutation.field(), &random_,
732
0
                                         size_increase_hint);
733
0
        for (const Message* source : sources) source_sampler.Sample(*source);
734
0
        if (source_sampler.IsEmpty()) break;
735
0
        CopyField()(source_sampler.field(), mutation.field());
736
0
        return true;
737
0
      }
738
0
      default:
739
0
        assert(false && "unexpected mutation");
740
0
        return false;
741
0
    }
742
743
    // Don't try same mutation next time.
744
0
    mutations[static_cast<size_t>(mutation.mutation())] = false;
745
0
  }
746
0
  return false;
747
0
}
748
749
0
int32_t Mutator::MutateInt32(int32_t value) { return FlipBit(value, &random_); }
750
751
0
int64_t Mutator::MutateInt64(int64_t value) { return FlipBit(value, &random_); }
752
753
0
uint32_t Mutator::MutateUInt32(uint32_t value) {
754
0
  return FlipBit(value, &random_);
755
0
}
756
757
0
uint64_t Mutator::MutateUInt64(uint64_t value) {
758
0
  return FlipBit(value, &random_);
759
0
}
760
761
0
float Mutator::MutateFloat(float value) { return FlipBit(value, &random_); }
762
763
0
double Mutator::MutateDouble(double value) { return FlipBit(value, &random_); }
764
765
0
bool Mutator::MutateBool(bool value) { return !value; }
766
767
0
size_t Mutator::MutateEnum(size_t index, size_t item_count) {
768
0
  if (item_count <= 1) return 0;
769
0
  return (index + 1 + GetRandomIndex(&random_, item_count - 1)) % item_count;
770
0
}
771
772
std::string Mutator::MutateString(const std::string& value,
773
0
                                  int size_increase_hint) {
774
0
  std::string result = value;
775
776
0
  while (!result.empty() && GetRandomBool(&random_)) {
777
0
    result.erase(GetRandomIndex(&random_, result.size()), 1);
778
0
  }
779
780
0
  while (size_increase_hint > 0 &&
781
0
         result.size() < static_cast<size_t>(size_increase_hint) &&
782
0
         GetRandomBool(&random_)) {
783
0
    size_t index = GetRandomIndex(&random_, result.size() + 1);
784
0
    result.insert(result.begin() + index, GetRandomIndex(&random_, 1 << 8));
785
0
  }
786
787
0
  if (result != value) return result;
788
789
0
  if (result.empty()) {
790
0
    result.push_back(GetRandomIndex(&random_, 1 << 8));
791
0
    return result;
792
0
  }
793
794
0
  if (!result.empty())
795
0
    FlipBit(result.size(), reinterpret_cast<uint8_t*>(&result[0]), &random_);
796
0
  return result;
797
0
}
798
799
std::string Mutator::MutateUtf8String(const std::string& value,
800
0
                                      int size_increase_hint) {
801
0
  std::string str = MutateString(value, size_increase_hint);
802
0
  FixUtf8String(&str, &random_);
803
0
  return str;
804
0
}
805
806
2.77k
bool Mutator::IsInitialized(const Message& message) const {
807
2.77k
  if (!keep_initialized_ || message.IsInitialized()) return true;
808
0
  std::cerr << "Uninitialized: " << message.DebugString() << "\n";
809
0
  return false;
810
2.77k
}
811
812
}  // namespace protobuf_mutator