diff options
author | Vitaly Buka <vitalybuka@google.com> | 2020-01-26 01:52:40 -0800 |
---|---|---|
committer | Vitaly Buka <vitalybuka@gmail.com> | 2020-02-04 13:05:49 -0800 |
commit | 5635a7ada064f9cbd328498cc9e31b86b0165b91 (patch) | |
tree | 01edb0535effbad6baaea3dadb3a98eb363a17f9 | |
parent | 5cd166ec45f1ef3d181a5addb37a81288b56ec7c (diff) | |
download | libprotobuf-mutator-5635a7ada064f9cbd328498cc9e31b86b0165b91.tar.gz |
Clone implementation
-rw-r--r-- | src/mutator.cc | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/mutator.cc b/src/mutator.cc index ac936cf..b1694f3 100644 --- a/src/mutator.cc +++ b/src/mutator.cc @@ -46,9 +46,7 @@ enum class Mutation { Mutate, // Mutates field contents. Delete, // Deletes field. Copy, // Copy values copied from another field. - - // TODO(vitalybuka): - // Clone, // Adds new field with value copied from another field. + Clone, // Create new field with value copied from another. }; // Return random integer from [0, count) @@ -205,6 +203,7 @@ class MutationSampler { oneof->field(GetRandomIndex(random_, oneof->field_count())); if (add_field != current_field) { Try({message, add_field}, Mutation::Add); + Try({message, add_field}, Mutation::Clone); break; } if (oneof->field_count() < 2) break; @@ -219,8 +218,9 @@ class MutationSampler { } else { if (field->is_repeated()) { int field_size = reflection->FieldSize(*message, field); - Try({message, field, GetRandomIndex(random_, field_size + 1)}, - Mutation::Add); + size_t random_index = GetRandomIndex(random_, field_size + 1); + Try({message, field, random_index}, Mutation::Add); + Try({message, field, random_index}, Mutation::Clone); if (field_size) { size_t random_index = GetRandomIndex(random_, field_size); @@ -241,6 +241,7 @@ class MutationSampler { Try({message, field}, Mutation::Copy); } else { Try({message, field}, Mutation::Add); + Try({message, field}, Mutation::Clone); } } } @@ -531,6 +532,14 @@ void Mutator::MutateImpl(const Message& source, Message* message, case Mutation::Delete: DeleteField()(mutation.field()); return; + case Mutation::Clone: { + CreateField()(mutation.field(), size_increase_hint, source, this); + DataSourceSampler source_sampler(mutation.field(), &random_, + size_increase_hint, source); + if (source_sampler.IsEmpty()) return; // CreateField is enough. + CopyField()(source_sampler.field(), mutation.field()); + return; + } case Mutation::Copy: { DataSourceSampler source_sampler(mutation.field(), &random_, size_increase_hint, source); |