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 <functional>
19 #include <map>
20 #include <random>
21 #include <string>
22 
23 #include "src/field_instance.h"
24 #include "src/utf8_fix.h"
25 #include "src/weighted_reservoir_sampler.h"
26 
27 namespace protobuf_mutator {
28 
29 using protobuf::Descriptor;
30 using protobuf::FieldDescriptor;
31 using protobuf::FileDescriptor;
32 using protobuf::Message;
33 using protobuf::OneofDescriptor;
34 using protobuf::Reflection;
35 using protobuf::util::MessageDifferencer;
36 using std::placeholders::_1;
37 
38 namespace {
39 
40 const int kMaxInitializeDepth = 200;
41 const uint64_t kDefaultMutateWeight = 1000000;
42 
43 enum class Mutation {
44   None,
45   Add,     // Adds new field with default value.
46   Mutate,  // Mutates field contents.
47   Delete,  // Deletes field.
48   Copy,    // Copy values copied from another field.
49 
50   // TODO(vitalybuka):
51   // Clone,  // Adds new field with value copied from another field.
52 };
53 
54 // Return random integer from [0, count)
GetRandomIndex(RandomEngine * random,size_t count)55 size_t GetRandomIndex(RandomEngine* random, size_t count) {
56   assert(count > 0);
57   if (count == 1) return 0;
58   return std::uniform_int_distribution<size_t>(0, count - 1)(*random);
59 }
60 
61 // Flips random bit in the buffer.
FlipBit(size_t size,uint8_t * bytes,RandomEngine * random)62 void FlipBit(size_t size, uint8_t* bytes, RandomEngine* random) {
63   size_t bit = GetRandomIndex(random, size * 8);
64   bytes[bit / 8] ^= (1u << (bit % 8));
65 }
66 
67 // Flips random bit in the value.
68 template <class T>
FlipBit(T value,RandomEngine * random)69 T FlipBit(T value, RandomEngine* random) {
70   FlipBit(sizeof(value), reinterpret_cast<uint8_t*>(&value), random);
71   return value;
72 }
73 
74 // Return true with probability about 1-of-n.
GetRandomBool(RandomEngine * random,size_t n=2)75 bool GetRandomBool(RandomEngine* random, size_t n = 2) {
76   return GetRandomIndex(random, n) == 0;
77 }
78 
IsProto3SimpleField(const FieldDescriptor & field)79 bool IsProto3SimpleField(const FieldDescriptor& field) {
80   assert(field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
81          field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2);
82   return field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
83          field.cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
84          !field.containing_oneof() && !field.is_repeated();
85 }
86 
87 struct CreateDefaultField : public FieldFunction<CreateDefaultField> {
88   template <class T>
ForTypeprotobuf_mutator::__anonb2429a380111::CreateDefaultField89   void ForType(const FieldInstance& field) const {
90     T value;
91     field.GetDefault(&value);
92     field.Create(value);
93   }
94 };
95 
96 struct DeleteField : public FieldFunction<DeleteField> {
97   template <class T>
ForTypeprotobuf_mutator::__anonb2429a380111::DeleteField98   void ForType(const FieldInstance& field) const {
99     field.Delete();
100   }
101 };
102 
103 struct CopyField : public FieldFunction<CopyField> {
104   template <class T>
ForTypeprotobuf_mutator::__anonb2429a380111::CopyField105   void ForType(const ConstFieldInstance& source,
106                const FieldInstance& field) const {
107     T value;
108     source.Load(&value);
109     field.Store(value);
110   }
111 };
112 
113 struct AppendField : public FieldFunction<AppendField> {
114   template <class T>
ForTypeprotobuf_mutator::__anonb2429a380111::AppendField115   void ForType(const ConstFieldInstance& source,
116                const FieldInstance& field) const {
117     T value;
118     source.Load(&value);
119     field.Create(value);
120   }
121 };
122 
123 class IsEqualValueField : public FieldFunction<IsEqualValueField, bool> {
124  public:
125   template <class T>
ForType(const ConstFieldInstance & a,const ConstFieldInstance & b) const126   bool ForType(const ConstFieldInstance& a, const ConstFieldInstance& b) const {
127     T aa;
128     a.Load(&aa);
129     T bb;
130     b.Load(&bb);
131     return IsEqual(aa, bb);
132   }
133 
134  private:
IsEqual(const ConstFieldInstance::Enum & a,const ConstFieldInstance::Enum & b) const135   bool IsEqual(const ConstFieldInstance::Enum& a,
136                const ConstFieldInstance::Enum& b) const {
137     assert(a.count == b.count);
138     return a.index == b.index;
139   }
140 
IsEqual(const std::unique_ptr<protobuf::Message> & a,const std::unique_ptr<protobuf::Message> & b) const141   bool IsEqual(const std::unique_ptr<protobuf::Message>& a,
142                const std::unique_ptr<protobuf::Message>& b) const {
143     return MessageDifferencer::Equals(*a, *b);
144   }
145 
146   template <class T>
IsEqual(const T & a,const T & b) const147   bool IsEqual(const T& a, const T& b) const {
148     return a == b;
149   }
150 };
151 
152 // Selects random field and mutation from the given proto message.
153 class MutationSampler {
154  public:
MutationSampler(bool keep_initialized,RandomEngine * random,Message * message)155   MutationSampler(bool keep_initialized, RandomEngine* random, Message* message)
156       : keep_initialized_(keep_initialized), random_(random), sampler_(random) {
157     Sample(message);
158     assert(mutation() != Mutation::None ||
159            message->GetDescriptor()->field_count() == 0);
160   }
161 
162   // Returns selected field.
field() const163   const FieldInstance& field() const { return sampler_.selected().field; }
164 
165   // Returns selected mutation.
mutation() const166   Mutation mutation() const { return sampler_.selected().mutation; }
167 
168  private:
Sample(Message * message)169   void Sample(Message* message) {
170     const Descriptor* descriptor = message->GetDescriptor();
171     const Reflection* reflection = message->GetReflection();
172 
173     int field_count = descriptor->field_count();
174     for (int i = 0; i < field_count; ++i) {
175       const FieldDescriptor* field = descriptor->field(i);
176       if (const OneofDescriptor* oneof = field->containing_oneof()) {
177         // Handle entire oneof group on the first field.
178         if (field->index_in_oneof() == 0) {
179           assert(oneof->field_count());
180           const FieldDescriptor* current_field =
181               reflection->GetOneofFieldDescriptor(*message, oneof);
182           for (;;) {
183             const FieldDescriptor* add_field =
184                 oneof->field(GetRandomIndex(random_, oneof->field_count()));
185             if (add_field != current_field) {
186               sampler_.Try(kDefaultMutateWeight,
187                            {{message, add_field}, Mutation::Add});
188               break;
189             }
190             if (oneof->field_count() < 2) break;
191           }
192           if (current_field) {
193             if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
194               sampler_.Try(kDefaultMutateWeight,
195                            {{message, current_field}, Mutation::Mutate});
196             }
197             sampler_.Try(kDefaultMutateWeight,
198                          {{message, current_field}, Mutation::Delete});
199             sampler_.Try(kDefaultMutateWeight,
200                          {{message, current_field}, Mutation::Copy});
201           }
202         }
203       } else {
204         if (field->is_repeated()) {
205           int field_size = reflection->FieldSize(*message, field);
206           sampler_.Try(
207               kDefaultMutateWeight,
208               {{message, field, GetRandomIndex(random_, field_size + 1)},
209                Mutation::Add});
210 
211           if (field_size) {
212             size_t random_index = GetRandomIndex(random_, field_size);
213             if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
214               sampler_.Try(kDefaultMutateWeight,
215                            {{message, field, random_index}, Mutation::Mutate});
216             }
217             sampler_.Try(kDefaultMutateWeight,
218                          {{message, field, random_index}, Mutation::Delete});
219             sampler_.Try(kDefaultMutateWeight,
220                          {{message, field, random_index}, Mutation::Copy});
221           }
222         } else {
223           if (reflection->HasField(*message, field) ||
224               IsProto3SimpleField(*field)) {
225             if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
226               sampler_.Try(kDefaultMutateWeight,
227                            {{message, field}, Mutation::Mutate});
228             if (!IsProto3SimpleField(*field) &&
229                 (!field->is_required() || !keep_initialized_)) {
230               sampler_.Try(kDefaultMutateWeight,
231                            {{message, field}, Mutation::Delete});
232             }
233             sampler_.Try(kDefaultMutateWeight,
234                          {{message, field}, Mutation::Copy});
235           } else {
236             sampler_.Try(kDefaultMutateWeight,
237                          {{message, field}, Mutation::Add});
238           }
239         }
240       }
241 
242       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
243         if (field->is_repeated()) {
244           const int field_size = reflection->FieldSize(*message, field);
245           for (int j = 0; j < field_size; ++j)
246             Sample(reflection->MutableRepeatedMessage(message, field, j));
247         } else if (reflection->HasField(*message, field)) {
248           Sample(reflection->MutableMessage(message, field));
249         }
250       }
251     }
252   }
253 
254   bool keep_initialized_ = false;
255 
256   RandomEngine* random_;
257 
258   struct Result {
259     Result() = default;
Resultprotobuf_mutator::__anonb2429a380111::MutationSampler::Result260     Result(const FieldInstance& f, Mutation m) : field(f), mutation(m) {}
261 
262     FieldInstance field;
263     Mutation mutation = Mutation::None;
264   };
265   WeightedReservoirSampler<Result, RandomEngine> sampler_;
266 };
267 
268 // Selects random field of compatible type to use for clone mutations.
269 class DataSourceSampler {
270  public:
DataSourceSampler(const ConstFieldInstance & match,RandomEngine * random,Message * message)271   DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random,
272                     Message* message)
273       : match_(match), random_(random), sampler_(random) {
274     Sample(message);
275   }
276 
277   // Returns selected field.
field() const278   const ConstFieldInstance& field() const {
279     assert(!IsEmpty());
280     return sampler_.selected();
281   }
282 
IsEmpty() const283   bool IsEmpty() const { return sampler_.IsEmpty(); }
284 
285  private:
Sample(Message * message)286   void Sample(Message* message) {
287     const Descriptor* descriptor = message->GetDescriptor();
288     const Reflection* reflection = message->GetReflection();
289 
290     int field_count = descriptor->field_count();
291     for (int i = 0; i < field_count; ++i) {
292       const FieldDescriptor* field = descriptor->field(i);
293       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
294         if (field->is_repeated()) {
295           const int field_size = reflection->FieldSize(*message, field);
296           for (int j = 0; j < field_size; ++j) {
297             Sample(reflection->MutableRepeatedMessage(message, field, j));
298           }
299         } else if (reflection->HasField(*message, field)) {
300           Sample(reflection->MutableMessage(message, field));
301         }
302       }
303 
304       if (field->cpp_type() != match_.cpp_type()) continue;
305       if (match_.cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
306         if (field->enum_type() != match_.enum_type()) continue;
307       } else if (match_.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
308         if (field->message_type() != match_.message_type()) continue;
309       }
310 
311       if (field->is_repeated()) {
312         if (int field_size = reflection->FieldSize(*message, field)) {
313           ConstFieldInstance source(message, field,
314                                     GetRandomIndex(random_, field_size));
315           if (match_.EnforceUtf8() && !source.EnforceUtf8()) continue;
316           if (!IsEqualValueField()(match_, source))
317             sampler_.Try(field_size, source);
318         }
319       } else {
320         if (reflection->HasField(*message, field)) {
321           ConstFieldInstance source(message, field);
322           if (match_.EnforceUtf8() && !source.EnforceUtf8()) continue;
323           if (!IsEqualValueField()(match_, source)) sampler_.Try(1, source);
324         }
325       }
326     }
327   }
328 
329   ConstFieldInstance match_;
330   RandomEngine* random_;
331 
332   WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_;
333 };
334 
335 }  // namespace
336 
337 class FieldMutator {
338  public:
FieldMutator(size_t size_increase_hint,bool enforce_changes,bool enforce_utf8_strings,Mutator * mutator)339   FieldMutator(size_t size_increase_hint, bool enforce_changes,
340                bool enforce_utf8_strings, Mutator* mutator)
341       : size_increase_hint_(size_increase_hint),
342         enforce_changes_(enforce_changes),
343         enforce_utf8_strings_(enforce_utf8_strings),
344         mutator_(mutator) {}
345 
Mutate(int32_t * value) const346   void Mutate(int32_t* value) const {
347     RepeatMutate(value, std::bind(&Mutator::MutateInt32, mutator_, _1));
348   }
349 
Mutate(int64_t * value) const350   void Mutate(int64_t* value) const {
351     RepeatMutate(value, std::bind(&Mutator::MutateInt64, mutator_, _1));
352   }
353 
Mutate(uint32_t * value) const354   void Mutate(uint32_t* value) const {
355     RepeatMutate(value, std::bind(&Mutator::MutateUInt32, mutator_, _1));
356   }
357 
Mutate(uint64_t * value) const358   void Mutate(uint64_t* value) const {
359     RepeatMutate(value, std::bind(&Mutator::MutateUInt64, mutator_, _1));
360   }
361 
Mutate(float * value) const362   void Mutate(float* value) const {
363     RepeatMutate(value, std::bind(&Mutator::MutateFloat, mutator_, _1));
364   }
365 
Mutate(double * value) const366   void Mutate(double* value) const {
367     RepeatMutate(value, std::bind(&Mutator::MutateDouble, mutator_, _1));
368   }
369 
Mutate(bool * value) const370   void Mutate(bool* value) const {
371     RepeatMutate(value, std::bind(&Mutator::MutateBool, mutator_, _1), 2);
372   }
373 
Mutate(FieldInstance::Enum * value) const374   void Mutate(FieldInstance::Enum* value) const {
375     RepeatMutate(&value->index,
376                  std::bind(&Mutator::MutateEnum, mutator_, _1, value->count),
377                  std::max<size_t>(value->count, 1));
378     assert(value->index < value->count);
379   }
380 
Mutate(std::string * value) const381   void Mutate(std::string* value) const {
382     if (enforce_utf8_strings_) {
383       RepeatMutate(value, std::bind(&Mutator::MutateUtf8String, mutator_, _1,
384                                     size_increase_hint_));
385     } else {
386       RepeatMutate(value, std::bind(&Mutator::MutateString, mutator_, _1,
387                                     size_increase_hint_));
388     }
389   }
390 
Mutate(std::unique_ptr<Message> * message) const391   void Mutate(std::unique_ptr<Message>* message) const {
392     assert(!enforce_changes_);
393     assert(*message);
394     if (GetRandomBool(mutator_->random(), 100)) return;
395     mutator_->Mutate(message->get(), size_increase_hint_);
396   }
397 
398  private:
399   template <class T, class F>
RepeatMutate(T * value,F mutate,size_t unchanged_one_out_of=100) const400   void RepeatMutate(T* value, F mutate,
401                     size_t unchanged_one_out_of = 100) const {
402     if (!enforce_changes_ &&
403         GetRandomBool(mutator_->random(), unchanged_one_out_of)) {
404       return;
405     }
406     T tmp = *value;
407     for (int i = 0; i < 10; ++i) {
408       *value = mutate(*value);
409       if (!enforce_changes_ || *value != tmp) return;
410     }
411   }
412 
413   size_t size_increase_hint_;
414   size_t enforce_changes_;
415   bool enforce_utf8_strings_;
416   Mutator* mutator_;
417 };
418 
419 namespace {
420 
421 struct MutateField : public FieldFunction<MutateField> {
422   template <class T>
ForTypeprotobuf_mutator::__anonb2429a380211::MutateField423   void ForType(const FieldInstance& field, size_t size_increase_hint,
424                Mutator* mutator) const {
425     T value;
426     field.Load(&value);
427     FieldMutator(size_increase_hint, true, field.EnforceUtf8(), mutator)
428         .Mutate(&value);
429     field.Store(value);
430   }
431 };
432 
433 struct CreateField : public FieldFunction<CreateField> {
434  public:
435   template <class T>
ForTypeprotobuf_mutator::__anonb2429a380211::CreateField436   void ForType(const FieldInstance& field, size_t size_increase_hint,
437                Mutator* mutator) const {
438     T value;
439     field.GetDefault(&value);
440     FieldMutator field_mutator(size_increase_hint,
441                                false /* defaults could be useful */,
442                                field.EnforceUtf8(), mutator);
443     field_mutator.Mutate(&value);
444     field.Create(value);
445   }
446 };
447 
448 }  // namespace
449 
Mutator(RandomEngine * random)450 Mutator::Mutator(RandomEngine* random) : random_(random) {}
451 
Mutate(Message * message,size_t size_increase_hint)452 void Mutator::Mutate(Message* message, size_t size_increase_hint) {
453   bool repeat;
454   do {
455     repeat = false;
456     MutationSampler mutation(keep_initialized_, random_, message);
457     switch (mutation.mutation()) {
458       case Mutation::None:
459         break;
460       case Mutation::Add:
461         CreateField()(mutation.field(), size_increase_hint / 2, this);
462         break;
463       case Mutation::Mutate:
464         MutateField()(mutation.field(), size_increase_hint / 2, this);
465         break;
466       case Mutation::Delete:
467         DeleteField()(mutation.field());
468         break;
469       case Mutation::Copy: {
470         DataSourceSampler source(mutation.field(), random_, message);
471         if (source.IsEmpty()) {
472           repeat = true;
473           break;
474         }
475         CopyField()(source.field(), mutation.field());
476         break;
477       }
478       default:
479         assert(false && "unexpected mutation");
480     }
481   } while (repeat);
482 
483   InitializeAndTrim(message, kMaxInitializeDepth);
484   assert(!keep_initialized_ || message->IsInitialized());
485 }
486 
CrossOver(const protobuf::Message & message1,protobuf::Message * message2)487 void Mutator::CrossOver(const protobuf::Message& message1,
488                         protobuf::Message* message2) {
489   // CrossOver can produce result which still equals to inputs. So we backup
490   // message2 to later comparison. message1 is already constant.
491   std::unique_ptr<protobuf::Message> message2_copy(message2->New());
492   message2_copy->CopyFrom(*message2);
493 
494   CrossOverImpl(message1, message2);
495 
496   InitializeAndTrim(message2, kMaxInitializeDepth);
497   assert(!keep_initialized_ || message2->IsInitialized());
498 
499   // Can't call mutate from crossover because of a bug in libFuzzer.
500   return;
501   // if (MessageDifferencer::Equals(*message2_copy, *message2) ||
502   //     MessageDifferencer::Equals(message1, *message2)) {
503   //   Mutate(message2, 0);
504   // }
505 }
506 
CrossOverImpl(const protobuf::Message & message1,protobuf::Message * message2)507 void Mutator::CrossOverImpl(const protobuf::Message& message1,
508                             protobuf::Message* message2) {
509   const Descriptor* descriptor = message2->GetDescriptor();
510   const Reflection* reflection = message2->GetReflection();
511   assert(message1.GetDescriptor() == descriptor);
512   assert(message1.GetReflection() == reflection);
513 
514   for (int i = 0; i < descriptor->field_count(); ++i) {
515     const FieldDescriptor* field = descriptor->field(i);
516 
517     if (field->is_repeated()) {
518       const int field_size1 = reflection->FieldSize(message1, field);
519       int field_size2 = reflection->FieldSize(*message2, field);
520       for (int j = 0; j < field_size1; ++j) {
521         ConstFieldInstance source(&message1, field, j);
522         FieldInstance destination(message2, field, field_size2++);
523         AppendField()(source, destination);
524       }
525 
526       assert(field_size2 == reflection->FieldSize(*message2, field));
527 
528       // Shuffle
529       for (int j = 0; j < field_size2; ++j) {
530         if (int k = GetRandomIndex(random_, field_size2 - j)) {
531           reflection->SwapElements(message2, field, j, j + k);
532         }
533       }
534 
535       int keep = GetRandomIndex(random_, field_size2 + 1);
536 
537       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
538         int remove = field_size2 - keep;
539         // Cross some message to keep with messages to remove.
540         int cross = GetRandomIndex(random_, std::min(keep, remove) + 1);
541         for (int j = 0; j < cross; ++j) {
542           int k = GetRandomIndex(random_, keep);
543           int r = keep + GetRandomIndex(random_, remove);
544           assert(k != r);
545           CrossOverImpl(reflection->GetRepeatedMessage(*message2, field, r),
546                         reflection->MutableRepeatedMessage(message2, field, k));
547         }
548       }
549 
550       for (int j = keep; j < field_size2; ++j)
551         reflection->RemoveLast(message2, field);
552       assert(keep == reflection->FieldSize(*message2, field));
553 
554     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
555       if (!reflection->HasField(message1, field)) {
556         if (GetRandomBool(random_))
557           DeleteField()(FieldInstance(message2, field));
558       } else if (!reflection->HasField(*message2, field)) {
559         if (GetRandomBool(random_)) {
560           ConstFieldInstance source(&message1, field);
561           CopyField()(source, FieldInstance(message2, field));
562         }
563       } else {
564         CrossOverImpl(reflection->GetMessage(message1, field),
565                       reflection->MutableMessage(message2, field));
566       }
567     } else {
568       if (GetRandomBool(random_)) {
569         if (reflection->HasField(message1, field)) {
570           ConstFieldInstance source(&message1, field);
571           CopyField()(source, FieldInstance(message2, field));
572         } else {
573           DeleteField()(FieldInstance(message2, field));
574         }
575       }
576     }
577   }
578 }
579 
InitializeAndTrim(Message * message,int max_depth)580 void Mutator::InitializeAndTrim(Message* message, int max_depth) {
581   const Descriptor* descriptor = message->GetDescriptor();
582   const Reflection* reflection = message->GetReflection();
583   for (int i = 0; i < descriptor->field_count(); ++i) {
584     const FieldDescriptor* field = descriptor->field(i);
585     if (keep_initialized_ && field->is_required() &&
586         !reflection->HasField(*message, field))
587       CreateDefaultField()(FieldInstance(message, field));
588 
589     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
590       if (max_depth <= 0 && !field->is_required()) {
591         // Clear deep optional fields to avoid stack overflow.
592         reflection->ClearField(message, field);
593         if (field->is_repeated())
594           assert(!reflection->FieldSize(*message, field));
595         else
596           assert(!reflection->HasField(*message, field));
597         continue;
598       }
599 
600       if (field->is_repeated()) {
601         const int field_size = reflection->FieldSize(*message, field);
602         for (int j = 0; j < field_size; ++j) {
603           Message* nested_message =
604               reflection->MutableRepeatedMessage(message, field, j);
605           InitializeAndTrim(nested_message, max_depth - 1);
606         }
607       } else if (reflection->HasField(*message, field)) {
608         Message* nested_message = reflection->MutableMessage(message, field);
609         InitializeAndTrim(nested_message, max_depth - 1);
610       }
611     }
612   }
613 }
614 
MutateInt32(int32_t value)615 int32_t Mutator::MutateInt32(int32_t value) { return FlipBit(value, random_); }
616 
MutateInt64(int64_t value)617 int64_t Mutator::MutateInt64(int64_t value) { return FlipBit(value, random_); }
618 
MutateUInt32(uint32_t value)619 uint32_t Mutator::MutateUInt32(uint32_t value) {
620   return FlipBit(value, random_);
621 }
622 
MutateUInt64(uint64_t value)623 uint64_t Mutator::MutateUInt64(uint64_t value) {
624   return FlipBit(value, random_);
625 }
626 
MutateFloat(float value)627 float Mutator::MutateFloat(float value) { return FlipBit(value, random_); }
628 
MutateDouble(double value)629 double Mutator::MutateDouble(double value) { return FlipBit(value, random_); }
630 
MutateBool(bool value)631 bool Mutator::MutateBool(bool value) { return !value; }
632 
MutateEnum(size_t index,size_t item_count)633 size_t Mutator::MutateEnum(size_t index, size_t item_count) {
634   if (item_count <= 1) return 0;
635   return (index + 1 + GetRandomIndex(random_, item_count - 1)) % item_count;
636 }
637 
MutateString(const std::string & value,size_t size_increase_hint)638 std::string Mutator::MutateString(const std::string& value,
639                                   size_t size_increase_hint) {
640   std::string result = value;
641 
642   while (!result.empty() && GetRandomBool(random_)) {
643     result.erase(GetRandomIndex(random_, result.size()), 1);
644   }
645 
646   while (result.size() < size_increase_hint && GetRandomBool(random_)) {
647     size_t index = GetRandomIndex(random_, result.size() + 1);
648     result.insert(result.begin() + index, GetRandomIndex(random_, 1 << 8));
649   }
650 
651   if (result != value) return result;
652 
653   if (result.empty()) {
654     result.push_back(GetRandomIndex(random_, 1 << 8));
655     return result;
656   }
657 
658   if (!result.empty())
659     FlipBit(result.size(), reinterpret_cast<uint8_t*>(&result[0]), random_);
660   return result;
661 }
662 
MutateUtf8String(const std::string & value,size_t size_increase_hint)663 std::string Mutator::MutateUtf8String(const std::string& value,
664                                       size_t size_increase_hint) {
665   std::string str = MutateString(value, size_increase_hint);
666   FixUtf8String(&str, random_);
667   return str;
668 }
669 
670 }  // namespace protobuf_mutator
671