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