blob: fb5542b15c994c4437420cf126ed9160889633bb [file] [log] [blame]
Vitaly Buka00b61072016-10-19 16:22:51 -07001// 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
Vitaly Bukaf90698f2017-03-01 15:46:58 -080015#include "src/mutator.h"
Vitaly Buka00b61072016-10-19 16:22:51 -070016
Vitaly Buka781853c2016-11-21 23:09:35 -080017#include <algorithm>
Vitaly Bukac1839912020-01-26 22:32:57 -080018#include <bitset>
Vitaly Bukaf48c32b2020-04-10 12:17:23 -070019#include <iostream>
Vitaly Buka0e17fd72016-11-18 10:02:46 -080020#include <map>
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -080021#include <memory>
Vitaly Buka781853c2016-11-21 23:09:35 -080022#include <random>
Vitaly Buka0e17fd72016-11-18 10:02:46 -080023#include <string>
Vitaly Buka3521f472020-02-04 16:19:41 -080024#include <utility>
Allen-Webbc4fa5912018-09-07 15:53:30 -070025#include <vector>
Vitaly Buka00b61072016-10-19 16:22:51 -070026
Vitaly Buka9dd2f8e2017-01-13 00:48:31 -080027#include "src/field_instance.h"
Vitaly Bukaaf8136f2017-06-09 16:40:12 -070028#include "src/utf8_fix.h"
Vitaly Buka9dd2f8e2017-01-13 00:48:31 -080029#include "src/weighted_reservoir_sampler.h"
Vitaly Buka00b61072016-10-19 16:22:51 -070030
Vitaly Bukaf86815c2017-02-27 14:19:19 -080031namespace protobuf_mutator {
32
Vitaly Bukae635fea2020-02-04 11:59:13 -080033using google::protobuf::Any;
Vitaly Buka6c6dbbe2017-02-22 13:58:24 -080034using protobuf::Descriptor;
Vitaly Buka6c6dbbe2017-02-22 13:58:24 -080035using protobuf::FieldDescriptor;
Vitaly Buka796b1122017-03-03 14:42:02 -080036using protobuf::FileDescriptor;
Vitaly Buka6c6dbbe2017-02-22 13:58:24 -080037using protobuf::Message;
38using protobuf::OneofDescriptor;
39using protobuf::Reflection;
Vitaly Buka4782c142017-03-04 00:12:32 -080040using protobuf::util::MessageDifferencer;
Vitaly Buka796b1122017-03-03 14:42:02 -080041using std::placeholders::_1;
Vitaly Buka0e17fd72016-11-18 10:02:46 -080042
43namespace {
44
Vitaly Bukae4eae602017-09-28 17:28:12 -070045const int kMaxInitializeDepth = 200;
Vitaly Buka329fa462017-03-15 16:52:17 -070046const uint64_t kDefaultMutateWeight = 1000000;
Vitaly Buka0e17fd72016-11-18 10:02:46 -080047
Vitaly Bukac1839912020-01-26 22:32:57 -080048enum class Mutation : uint8_t {
Vitaly Buka30de3092016-11-18 11:39:07 -080049 None,
Vitaly Buka4af611d2016-12-03 18:57:32 -080050 Add, // Adds new field with default value.
51 Mutate, // Mutates field contents.
52 Delete, // Deletes field.
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080053 Copy, // Copy values copied from another field.
Vitaly Buka5635a7a2020-01-26 01:52:40 -080054 Clone, // Create new field with value copied from another.
Vitaly Bukac1839912020-01-26 22:32:57 -080055
56 Last = Clone,
Vitaly Buka0e17fd72016-11-18 10:02:46 -080057};
58
Vitaly Buka68e10c12020-03-26 13:41:33 -070059using MutationBitset = std::bitset<static_cast<size_t>(Mutation::Last) + 1>;
Vitaly Bukac1839912020-01-26 22:32:57 -080060
Vitaly Bukaf62086c2020-01-29 01:11:23 -080061using Messages = std::vector<Message*>;
62using ConstMessages = std::vector<const Message*>;
63
Vitaly Bukab592ff02017-03-03 14:35:52 -080064// Return random integer from [0, count)
Vitaly Bukaf62fe472017-03-01 23:05:15 -080065size_t GetRandomIndex(RandomEngine* random, size_t count) {
Vitaly Bukab592ff02017-03-03 14:35:52 -080066 assert(count > 0);
67 if (count == 1) return 0;
68 return std::uniform_int_distribution<size_t>(0, count - 1)(*random);
69}
70
Vitaly Buka4af611d2016-12-03 18:57:32 -080071// Flips random bit in the buffer.
Vitaly Bukaf62fe472017-03-01 23:05:15 -080072void FlipBit(size_t size, uint8_t* bytes, RandomEngine* random) {
Vitaly Bukab592ff02017-03-03 14:35:52 -080073 size_t bit = GetRandomIndex(random, size * 8);
Vitaly Buka4af611d2016-12-03 18:57:32 -080074 bytes[bit / 8] ^= (1u << (bit % 8));
75}
Vitaly Buka781853c2016-11-21 23:09:35 -080076
Vitaly Buka4af611d2016-12-03 18:57:32 -080077// Flips random bit in the value.
78template <class T>
Vitaly Bukaf62fe472017-03-01 23:05:15 -080079T FlipBit(T value, RandomEngine* random) {
Vitaly Buka4af611d2016-12-03 18:57:32 -080080 FlipBit(sizeof(value), reinterpret_cast<uint8_t*>(&value), random);
81 return value;
82}
Vitaly Buka781853c2016-11-21 23:09:35 -080083
Vitaly Bukabeb90802017-02-28 15:28:10 -080084// Return true with probability about 1-of-n.
Vitaly Bukaf62fe472017-03-01 23:05:15 -080085bool GetRandomBool(RandomEngine* random, size_t n = 2) {
Vitaly Bukabeb90802017-02-28 15:28:10 -080086 return GetRandomIndex(random, n) == 0;
87}
88
Vitaly Buka28ca0ee2017-03-04 21:35:42 -080089bool IsProto3SimpleField(const FieldDescriptor& field) {
90 assert(field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
91 field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2);
92 return field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
93 field.cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
94 !field.containing_oneof() && !field.is_repeated();
95}
96
Vitaly Bukad4ab1e72017-03-03 23:51:19 -080097struct CreateDefaultField : public FieldFunction<CreateDefaultField> {
Vitaly Buka91ad7b02016-12-12 15:41:41 -080098 template <class T>
Vitaly Bukad4ab1e72017-03-03 23:51:19 -080099 void ForType(const FieldInstance& field) const {
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800100 T value;
101 field.GetDefault(&value);
102 field.Create(value);
Vitaly Bukabec52222016-12-09 14:29:32 -0800103 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800104};
Vitaly Bukabec52222016-12-09 14:29:32 -0800105
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800106struct DeleteField : public FieldFunction<DeleteField> {
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800107 template <class T>
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800108 void ForType(const FieldInstance& field) const {
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800109 field.Delete();
Vitaly Bukabec52222016-12-09 14:29:32 -0800110 }
Vitaly Bukabec52222016-12-09 14:29:32 -0800111};
112
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800113struct CopyField : public FieldFunction<CopyField> {
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800114 template <class T>
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800115 void ForType(const ConstFieldInstance& source,
116 const FieldInstance& field) const {
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800117 T value;
118 source.Load(&value);
119 field.Store(value);
120 }
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800121};
122
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800123struct AppendField : public FieldFunction<AppendField> {
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800124 template <class T>
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800125 void ForType(const ConstFieldInstance& source,
126 const FieldInstance& field) const {
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800127 T value;
128 source.Load(&value);
129 field.Create(value);
130 }
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800131};
132
Vitaly Buka2792ed72019-01-23 11:04:24 -0800133class CanCopyAndDifferentField
134 : public FieldFunction<CanCopyAndDifferentField, bool> {
Vitaly Buka4782c142017-03-04 00:12:32 -0800135 public:
136 template <class T>
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800137 bool ForType(const ConstFieldInstance& src, const ConstFieldInstance& dst,
138 int size_increase_hint) const {
Vitaly Buka2792ed72019-01-23 11:04:24 -0800139 T s;
140 src.Load(&s);
141 if (!dst.CanStore(s)) return false;
142 T d;
143 dst.Load(&d);
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800144 return SizeDiff(s, d) <= size_increase_hint && !IsEqual(s, d);
Vitaly Buka4782c142017-03-04 00:12:32 -0800145 }
146
147 private:
148 bool IsEqual(const ConstFieldInstance::Enum& a,
149 const ConstFieldInstance::Enum& b) const {
150 assert(a.count == b.count);
151 return a.index == b.index;
152 }
153
Vitaly Bukad3600272020-01-26 23:24:10 -0800154 bool IsEqual(const std::unique_ptr<Message>& a,
155 const std::unique_ptr<Message>& b) const {
Vitaly Buka4782c142017-03-04 00:12:32 -0800156 return MessageDifferencer::Equals(*a, *b);
157 }
158
159 template <class T>
160 bool IsEqual(const T& a, const T& b) const {
161 return a == b;
162 }
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800163
Vitaly Bukad3600272020-01-26 23:24:10 -0800164 int64_t SizeDiff(const std::unique_ptr<Message>& src,
165 const std::unique_ptr<Message>& dst) const {
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800166 return src->ByteSizeLong() - dst->ByteSizeLong();
167 }
168
169 int64_t SizeDiff(const std::string& src, const std::string& dst) const {
170 return src.size() - dst.size();
171 }
172
173 template <class T>
174 int64_t SizeDiff(const T&, const T&) const {
175 return 0;
176 }
Vitaly Buka4782c142017-03-04 00:12:32 -0800177};
178
Vitaly Buka4af611d2016-12-03 18:57:32 -0800179// Selects random field and mutation from the given proto message.
Vitaly Buka781853c2016-11-21 23:09:35 -0800180class MutationSampler {
Vitaly Bukac9d22482016-11-21 13:29:17 -0800181 public:
Vitaly Bukac1839912020-01-26 22:32:57 -0800182 MutationSampler(bool keep_initialized, MutationBitset allowed_mutations,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800183 RandomEngine* random)
Vitaly Buka4908d252020-01-24 19:10:34 -0800184 : keep_initialized_(keep_initialized),
Vitaly Bukac1839912020-01-26 22:32:57 -0800185 allowed_mutations_(allowed_mutations),
Vitaly Buka4908d252020-01-24 19:10:34 -0800186 random_(random),
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800187 sampler_(random) {}
Vitaly Bukac9d22482016-11-21 13:29:17 -0800188
Vitaly Buka4af611d2016-12-03 18:57:32 -0800189 // Returns selected field.
Vitaly Bukabec52222016-12-09 14:29:32 -0800190 const FieldInstance& field() const { return sampler_.selected().field; }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800191
192 // Returns selected mutation.
Vitaly Buka432b5452016-12-09 14:42:09 -0800193 Mutation mutation() const { return sampler_.selected().mutation; }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800194
Vitaly Buka781853c2016-11-21 23:09:35 -0800195 void Sample(Message* message) {
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800196 SampleImpl(message);
197 assert(mutation() != Mutation::None ||
198 !allowed_mutations_[static_cast<size_t>(Mutation::Mutate)] ||
199 message->GetDescriptor()->field_count() == 0);
200 }
201
202 private:
203 void SampleImpl(Message* message) {
Vitaly Buka781853c2016-11-21 23:09:35 -0800204 const Descriptor* descriptor = message->GetDescriptor();
205 const Reflection* reflection = message->GetReflection();
206
207 int field_count = descriptor->field_count();
208 for (int i = 0; i < field_count; ++i) {
209 const FieldDescriptor* field = descriptor->field(i);
210 if (const OneofDescriptor* oneof = field->containing_oneof()) {
211 // Handle entire oneof group on the first field.
212 if (field->index_in_oneof() == 0) {
Vitaly Buka2f660a52017-03-03 19:46:14 -0800213 assert(oneof->field_count());
214 const FieldDescriptor* current_field =
215 reflection->GetOneofFieldDescriptor(*message, oneof);
216 for (;;) {
217 const FieldDescriptor* add_field =
218 oneof->field(GetRandomIndex(random_, oneof->field_count()));
219 if (add_field != current_field) {
Vitaly Buka4908d252020-01-24 19:10:34 -0800220 Try({message, add_field}, Mutation::Add);
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800221 Try({message, add_field}, Mutation::Clone);
Vitaly Buka2f660a52017-03-03 19:46:14 -0800222 break;
223 }
224 if (oneof->field_count() < 2) break;
225 }
226 if (current_field) {
Vitaly Buka4908d252020-01-24 19:10:34 -0800227 if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
228 Try({message, current_field}, Mutation::Mutate);
229 Try({message, current_field}, Mutation::Delete);
230 Try({message, current_field}, Mutation::Copy);
Vitaly Buka781853c2016-11-21 23:09:35 -0800231 }
232 }
233 } else {
234 if (field->is_repeated()) {
Vitaly Bukabec52222016-12-09 14:29:32 -0800235 int field_size = reflection->FieldSize(*message, field);
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800236 size_t random_index = GetRandomIndex(random_, field_size + 1);
237 Try({message, field, random_index}, Mutation::Add);
238 Try({message, field, random_index}, Mutation::Clone);
Vitaly Buka781853c2016-11-21 23:09:35 -0800239
Vitaly Bukabec52222016-12-09 14:29:32 -0800240 if (field_size) {
241 size_t random_index = GetRandomIndex(random_, field_size);
Vitaly Buka4908d252020-01-24 19:10:34 -0800242 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
243 Try({message, field, random_index}, Mutation::Mutate);
244 Try({message, field, random_index}, Mutation::Delete);
245 Try({message, field, random_index}, Mutation::Copy);
Vitaly Buka781853c2016-11-21 23:09:35 -0800246 }
247 } else {
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800248 if (reflection->HasField(*message, field) ||
249 IsProto3SimpleField(*field)) {
Vitaly Buka4908d252020-01-24 19:10:34 -0800250 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
251 Try({message, field}, Mutation::Mutate);
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800252 if (!IsProto3SimpleField(*field) &&
253 (!field->is_required() || !keep_initialized_)) {
Vitaly Buka4908d252020-01-24 19:10:34 -0800254 Try({message, field}, Mutation::Delete);
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800255 }
Vitaly Buka4908d252020-01-24 19:10:34 -0800256 Try({message, field}, Mutation::Copy);
Vitaly Buka781853c2016-11-21 23:09:35 -0800257 } else {
Vitaly Buka4908d252020-01-24 19:10:34 -0800258 Try({message, field}, Mutation::Add);
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800259 Try({message, field}, Mutation::Clone);
Vitaly Buka781853c2016-11-21 23:09:35 -0800260 }
261 }
262 }
263
264 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
265 if (field->is_repeated()) {
266 const int field_size = reflection->FieldSize(*message, field);
267 for (int j = 0; j < field_size; ++j)
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800268 SampleImpl(reflection->MutableRepeatedMessage(message, field, j));
Vitaly Buka781853c2016-11-21 23:09:35 -0800269 } else if (reflection->HasField(*message, field)) {
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800270 SampleImpl(reflection->MutableMessage(message, field));
Vitaly Buka781853c2016-11-21 23:09:35 -0800271 }
272 }
273 }
274 }
275
Vitaly Buka4908d252020-01-24 19:10:34 -0800276 void Try(const FieldInstance& field, Mutation mutation) {
277 assert(mutation != Mutation::None);
Vitaly Bukac1839912020-01-26 22:32:57 -0800278 if (!allowed_mutations_[static_cast<size_t>(mutation)]) return;
Vitaly Buka4908d252020-01-24 19:10:34 -0800279 sampler_.Try(kDefaultMutateWeight, {field, mutation});
280 }
281
Vitaly Buka781853c2016-11-21 23:09:35 -0800282 bool keep_initialized_ = false;
Vitaly Bukac1839912020-01-26 22:32:57 -0800283 MutationBitset allowed_mutations_;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800284
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800285 RandomEngine* random_;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800286
287 struct Result {
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800288 Result() = default;
Vitaly Bukabec52222016-12-09 14:29:32 -0800289 Result(const FieldInstance& f, Mutation m) : field(f), mutation(m) {}
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800290
Vitaly Bukabec52222016-12-09 14:29:32 -0800291 FieldInstance field;
292 Mutation mutation = Mutation::None;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800293 };
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800294 WeightedReservoirSampler<Result, RandomEngine> sampler_;
Vitaly Bukac9d22482016-11-21 13:29:17 -0800295};
296
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800297// Selects random field of compatible type to use for clone mutations.
298class DataSourceSampler {
299 public:
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800300 DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800301 int size_increase_hint)
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800302 : match_(match),
303 random_(random),
304 size_increase_hint_(size_increase_hint),
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800305 sampler_(random) {}
306
307 void Sample(const Message& message) { SampleImpl(message); }
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800308
309 // Returns selected field.
Vitaly Buka88712862017-02-26 22:21:30 -0800310 const ConstFieldInstance& field() const {
Vitaly Buka72019dc2016-12-14 19:17:24 -0800311 assert(!IsEmpty());
312 return sampler_.selected();
313 }
314
315 bool IsEmpty() const { return sampler_.IsEmpty(); }
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800316
317 private:
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800318 void SampleImpl(const Message& message) {
Vitaly Buka0f63f912020-01-24 15:02:45 -0800319 const Descriptor* descriptor = message.GetDescriptor();
320 const Reflection* reflection = message.GetReflection();
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800321
322 int field_count = descriptor->field_count();
323 for (int i = 0; i < field_count; ++i) {
324 const FieldDescriptor* field = descriptor->field(i);
325 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
326 if (field->is_repeated()) {
Vitaly Buka0f63f912020-01-24 15:02:45 -0800327 const int field_size = reflection->FieldSize(message, field);
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800328 for (int j = 0; j < field_size; ++j) {
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800329 SampleImpl(reflection->GetRepeatedMessage(message, field, j));
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800330 }
Vitaly Buka0f63f912020-01-24 15:02:45 -0800331 } else if (reflection->HasField(message, field)) {
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800332 SampleImpl(reflection->GetMessage(message, field));
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800333 }
334 }
335
336 if (field->cpp_type() != match_.cpp_type()) continue;
337 if (match_.cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
338 if (field->enum_type() != match_.enum_type()) continue;
339 } else if (match_.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
340 if (field->message_type() != match_.message_type()) continue;
341 }
342
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800343 if (field->is_repeated()) {
Vitaly Buka0f63f912020-01-24 15:02:45 -0800344 if (int field_size = reflection->FieldSize(message, field)) {
345 ConstFieldInstance source(&message, field,
Vitaly Buka4782c142017-03-04 00:12:32 -0800346 GetRandomIndex(random_, field_size));
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800347 if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
Vitaly Buka4782c142017-03-04 00:12:32 -0800348 sampler_.Try(field_size, source);
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800349 }
350 } else {
Vitaly Buka0f63f912020-01-24 15:02:45 -0800351 if (reflection->HasField(message, field)) {
352 ConstFieldInstance source(&message, field);
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800353 if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
Vitaly Buka2792ed72019-01-23 11:04:24 -0800354 sampler_.Try(1, source);
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800355 }
356 }
357 }
358 }
359
Vitaly Buka88712862017-02-26 22:21:30 -0800360 ConstFieldInstance match_;
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800361 RandomEngine* random_;
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800362 int size_increase_hint_;
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800363
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800364 WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_;
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800365};
366
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800367using UnpackedAny =
368 std::unordered_map<const Message*, std::unique_ptr<Message>>;
369
370const Descriptor* GetAnyTypeDescriptor(const Any& any) {
371 std::string type_name;
Vitaly Bukae635fea2020-02-04 11:59:13 -0800372 if (!Any::ParseAnyTypeUrl(std::string(any.type_url()), &type_name))
373 return nullptr;
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800374 return any.descriptor()->file()->pool()->FindMessageTypeByName(type_name);
375}
376
377std::unique_ptr<Message> UnpackAny(const Any& any) {
378 const Descriptor* desc = GetAnyTypeDescriptor(any);
379 if (!desc) return {};
380 std::unique_ptr<Message> message(
381 any.GetReflection()->GetMessageFactory()->GetPrototype(desc)->New());
Vitaly Bukae635fea2020-02-04 11:59:13 -0800382 message->ParsePartialFromString(std::string(any.value()));
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800383 return message;
384}
385
386const Any* CastToAny(const Message* message) {
387 return Any::GetDescriptor() == message->GetDescriptor()
388 ? static_cast<const Any*>(message)
389 : nullptr;
390}
391
392Any* CastToAny(Message* message) {
393 return Any::GetDescriptor() == message->GetDescriptor()
394 ? static_cast<Any*>(message)
395 : nullptr;
396}
397
398std::unique_ptr<Message> UnpackIfAny(const Message& message) {
399 if (const Any* any = CastToAny(&message)) return UnpackAny(*any);
400 return {};
401}
402
403void UnpackAny(const Message& message, UnpackedAny* result) {
404 if (std::unique_ptr<Message> any = UnpackIfAny(message)) {
405 UnpackAny(*any, result);
406 result->emplace(&message, std::move(any));
407 return;
408 }
409
410 const Descriptor* descriptor = message.GetDescriptor();
411 const Reflection* reflection = message.GetReflection();
412
413 for (int i = 0; i < descriptor->field_count(); ++i) {
414 const FieldDescriptor* field = descriptor->field(i);
415 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
416 if (field->is_repeated()) {
417 const int field_size = reflection->FieldSize(message, field);
418 for (int j = 0; j < field_size; ++j) {
419 UnpackAny(reflection->GetRepeatedMessage(message, field, j), result);
420 }
421 } else if (reflection->HasField(message, field)) {
422 UnpackAny(reflection->GetMessage(message, field), result);
423 }
424 }
425 }
426}
427
Vitaly Buka045acda2020-01-29 00:26:35 -0800428class PostProcessing {
429 public:
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800430 using PostProcessors =
431 std::unordered_multimap<const Descriptor*, Mutator::PostProcess>;
Vitaly Buka045acda2020-01-29 00:26:35 -0800432
433 PostProcessing(bool keep_initialized, const PostProcessors& post_processors,
Vitaly Buka3521f472020-02-04 16:19:41 -0800434 const UnpackedAny& any, RandomEngine* random)
Vitaly Buka045acda2020-01-29 00:26:35 -0800435 : keep_initialized_(keep_initialized),
436 post_processors_(post_processors),
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800437 any_(any),
Vitaly Buka045acda2020-01-29 00:26:35 -0800438 random_(random) {}
439
440 void Run(Message* message, int max_depth) {
441 --max_depth;
442 const Descriptor* descriptor = message->GetDescriptor();
443
444 // Apply custom mutators in nested messages before packing any.
445 const Reflection* reflection = message->GetReflection();
446 for (int i = 0; i < descriptor->field_count(); i++) {
447 const FieldDescriptor* field = descriptor->field(i);
448 if (keep_initialized_ &&
449 (field->is_required() || descriptor->options().map_entry()) &&
450 !reflection->HasField(*message, field)) {
451 CreateDefaultField()(FieldInstance(message, field));
452 }
453
454 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
455
456 if (max_depth < 0 && !field->is_required()) {
457 // Clear deep optional fields to avoid stack overflow.
458 reflection->ClearField(message, field);
459 if (field->is_repeated())
460 assert(!reflection->FieldSize(*message, field));
461 else
462 assert(!reflection->HasField(*message, field));
463 continue;
464 }
465
466 if (field->is_repeated()) {
467 const int field_size = reflection->FieldSize(*message, field);
468 for (int j = 0; j < field_size; ++j) {
469 Message* nested_message =
470 reflection->MutableRepeatedMessage(message, field, j);
471 Run(nested_message, max_depth);
472 }
473 } else if (reflection->HasField(*message, field)) {
474 Message* nested_message = reflection->MutableMessage(message, field);
475 Run(nested_message, max_depth);
476 }
477 }
478
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800479 if (Any* any = CastToAny(message)) {
480 if (max_depth < 0) {
481 // Clear deep Any fields to avoid stack overflow.
482 any->Clear();
483 } else {
484 auto It = any_.find(message);
485 if (It != any_.end()) {
486 Run(It->second.get(), max_depth);
Vitaly Bukae635fea2020-02-04 11:59:13 -0800487 std::string value;
488 It->second->SerializePartialToString(&value);
489 *any->mutable_value() = value;
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800490 }
491 }
492 }
493
494 // Call user callback after message trimmed, initialized and packed.
Vitaly Buka045acda2020-01-29 00:26:35 -0800495 auto range = post_processors_.equal_range(descriptor);
496 for (auto it = range.first; it != range.second; ++it)
497 it->second(message, (*random_)());
498 }
499
500 private:
501 bool keep_initialized_;
502 const PostProcessors& post_processors_;
Vitaly Buka3521f472020-02-04 16:19:41 -0800503 const UnpackedAny& any_;
Vitaly Buka045acda2020-01-29 00:26:35 -0800504 RandomEngine* random_;
505};
506
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800507} // namespace
508
Vitaly Buka5d013202017-02-24 16:50:11 -0800509class FieldMutator {
Vitaly Buka432b5452016-12-09 14:42:09 -0800510 public:
Vitaly Buka1c91e722020-01-25 21:56:22 -0800511 FieldMutator(int size_increase_hint, bool enforce_changes,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800512 bool enforce_utf8_strings, const ConstMessages& sources,
Vitaly Buka0f63f912020-01-24 15:02:45 -0800513 Mutator* mutator)
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700514 : size_increase_hint_(size_increase_hint),
515 enforce_changes_(enforce_changes),
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700516 enforce_utf8_strings_(enforce_utf8_strings),
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800517 sources_(sources),
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700518 mutator_(mutator) {}
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800519
Vitaly Buka796b1122017-03-03 14:42:02 -0800520 void Mutate(int32_t* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800521 RepeatMutate(value, std::bind(&Mutator::MutateInt32, mutator_, _1));
Vitaly Buka796b1122017-03-03 14:42:02 -0800522 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800523
Vitaly Buka796b1122017-03-03 14:42:02 -0800524 void Mutate(int64_t* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800525 RepeatMutate(value, std::bind(&Mutator::MutateInt64, mutator_, _1));
Vitaly Buka796b1122017-03-03 14:42:02 -0800526 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800527
528 void Mutate(uint32_t* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800529 RepeatMutate(value, std::bind(&Mutator::MutateUInt32, mutator_, _1));
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800530 }
531
532 void Mutate(uint64_t* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800533 RepeatMutate(value, std::bind(&Mutator::MutateUInt64, mutator_, _1));
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800534 }
535
Vitaly Buka796b1122017-03-03 14:42:02 -0800536 void Mutate(float* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800537 RepeatMutate(value, std::bind(&Mutator::MutateFloat, mutator_, _1));
Vitaly Buka796b1122017-03-03 14:42:02 -0800538 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800539
Vitaly Buka796b1122017-03-03 14:42:02 -0800540 void Mutate(double* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800541 RepeatMutate(value, std::bind(&Mutator::MutateDouble, mutator_, _1));
Vitaly Buka796b1122017-03-03 14:42:02 -0800542 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800543
Vitaly Buka796b1122017-03-03 14:42:02 -0800544 void Mutate(bool* value) const {
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800545 RepeatMutate(value, std::bind(&Mutator::MutateBool, mutator_, _1));
Vitaly Buka796b1122017-03-03 14:42:02 -0800546 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800547
548 void Mutate(FieldInstance::Enum* value) const {
Vitaly Bukae79e0182017-03-01 16:02:14 -0800549 RepeatMutate(&value->index,
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800550 std::bind(&Mutator::MutateEnum, mutator_, _1, value->count));
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800551 assert(value->index < value->count);
552 }
553
554 void Mutate(std::string* value) const {
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700555 if (enforce_utf8_strings_) {
556 RepeatMutate(value, std::bind(&Mutator::MutateUtf8String, mutator_, _1,
557 size_increase_hint_));
558 } else {
559 RepeatMutate(value, std::bind(&Mutator::MutateString, mutator_, _1,
560 size_increase_hint_));
561 }
Vitaly Buka91ad7b02016-12-12 15:41:41 -0800562 }
563
Vitaly Bukab2c4fb52017-03-16 11:50:40 -0700564 void Mutate(std::unique_ptr<Message>* message) const {
565 assert(!enforce_changes_);
566 assert(*message);
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800567 if (GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_))
568 return;
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800569 mutator_->MutateImpl(sources_, {message->get()}, false,
570 size_increase_hint_);
Vitaly Bukab2c4fb52017-03-16 11:50:40 -0700571 }
Vitaly Buka432b5452016-12-09 14:42:09 -0800572
Vitaly Buka5d013202017-02-24 16:50:11 -0800573 private:
Vitaly Buka796b1122017-03-03 14:42:02 -0800574 template <class T, class F>
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800575 void RepeatMutate(T* value, F mutate) const {
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700576 if (!enforce_changes_ &&
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800577 GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_)) {
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700578 return;
Vitaly Bukab2c4fb52017-03-16 11:50:40 -0700579 }
Vitaly Buka796b1122017-03-03 14:42:02 -0800580 T tmp = *value;
581 for (int i = 0; i < 10; ++i) {
582 *value = mutate(*value);
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700583 if (!enforce_changes_ || *value != tmp) return;
Vitaly Buka796b1122017-03-03 14:42:02 -0800584 }
585 }
586
Vitaly Buka1c91e722020-01-25 21:56:22 -0800587 int size_increase_hint_;
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700588 size_t enforce_changes_;
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700589 bool enforce_utf8_strings_;
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800590 const ConstMessages& sources_;
Vitaly Bukae79e0182017-03-01 16:02:14 -0800591 Mutator* mutator_;
Vitaly Buka432b5452016-12-09 14:42:09 -0800592};
593
Vitaly Buka5d013202017-02-24 16:50:11 -0800594namespace {
595
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800596struct MutateField : public FieldFunction<MutateField> {
Vitaly Buka5d013202017-02-24 16:50:11 -0800597 template <class T>
Vitaly Buka1c91e722020-01-25 21:56:22 -0800598 void ForType(const FieldInstance& field, int size_increase_hint,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800599 const ConstMessages& sources, Mutator* mutator) const {
Vitaly Buka5d013202017-02-24 16:50:11 -0800600 T value;
601 field.Load(&value);
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800602 FieldMutator(size_increase_hint, true, field.EnforceUtf8(), sources,
603 mutator)
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700604 .Mutate(&value);
Vitaly Buka5d013202017-02-24 16:50:11 -0800605 field.Store(value);
606 }
Vitaly Buka5d013202017-02-24 16:50:11 -0800607};
608
Vitaly Bukad4ab1e72017-03-03 23:51:19 -0800609struct CreateField : public FieldFunction<CreateField> {
Vitaly Buka5d013202017-02-24 16:50:11 -0800610 public:
Vitaly Buka5d013202017-02-24 16:50:11 -0800611 template <class T>
Vitaly Buka1c91e722020-01-25 21:56:22 -0800612 void ForType(const FieldInstance& field, int size_increase_hint,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800613 const ConstMessages& sources, Mutator* mutator) const {
Vitaly Buka5d013202017-02-24 16:50:11 -0800614 T value;
615 field.GetDefault(&value);
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700616 FieldMutator field_mutator(size_increase_hint,
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700617 false /* defaults could be useful */,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800618 field.EnforceUtf8(), sources, mutator);
Vitaly Buka0e9439f2017-03-15 17:51:57 -0700619 field_mutator.Mutate(&value);
Vitaly Buka5d013202017-02-24 16:50:11 -0800620 field.Create(value);
621 }
Vitaly Buka5d013202017-02-24 16:50:11 -0800622};
623
624} // namespace
625
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700626void Mutator::Seed(uint32_t value) { random_.seed(value); }
Vitaly Buka432b5452016-12-09 14:42:09 -0800627
Vitaly Bukad82b5fb2020-07-28 23:41:42 -0700628void Mutator::Fix(Message* message) {
629 UnpackedAny any;
630 UnpackAny(*message, &any);
631
632 PostProcessing(keep_initialized_, post_processors_, any, &random_)
633 .Run(message, kMaxInitializeDepth);
634 assert(IsInitialized(*message));
635}
636
Vitaly Bukabaa13292020-01-25 19:39:28 -0800637void Mutator::Mutate(Message* message, size_t max_size_hint) {
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800638 UnpackedAny any;
639 UnpackAny(*message, &any);
640
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800641 Messages messages;
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800642 messages.reserve(any.size() + 1);
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800643 messages.push_back(message);
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800644 for (const auto& kv : any) messages.push_back(kv.second.get());
645
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800646 ConstMessages sources(messages.begin(), messages.end());
647 MutateImpl(sources, messages, false,
Vitaly Buka1c91e722020-01-25 21:56:22 -0800648 static_cast<int>(max_size_hint) -
649 static_cast<int>(message->ByteSizeLong()));
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800650
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800651 PostProcessing(keep_initialized_, post_processors_, any, &random_)
Vitaly Buka045acda2020-01-29 00:26:35 -0800652 .Run(message, kMaxInitializeDepth);
Vitaly Buka9eaf0632020-01-15 17:30:20 -0800653 assert(IsInitialized(*message));
Peter Foleyfe76ed62019-09-30 17:03:37 -0700654}
655
Vitaly Buka4b3d7832020-01-29 00:34:12 -0800656void Mutator::CrossOver(const Message& message1, Message* message2,
657 size_t max_size_hint) {
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800658 UnpackedAny any;
659 UnpackAny(*message2, &any);
660
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800661 Messages messages;
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800662 messages.reserve(any.size() + 1);
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800663 messages.push_back(message2);
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800664 for (auto& kv : any) messages.push_back(kv.second.get());
665
666 UnpackAny(message1, &any);
667
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800668 ConstMessages sources;
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800669 sources.reserve(any.size() + 2);
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800670 sources.push_back(&message1);
Vitaly Buka1989ccb2020-02-04 15:40:30 -0800671 sources.push_back(message2);
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800672 for (const auto& kv : any) sources.push_back(kv.second.get());
Vitaly Buka4b3d7832020-01-29 00:34:12 -0800673
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800674 MutateImpl(sources, messages, true,
675 static_cast<int>(max_size_hint) -
676 static_cast<int>(message2->ByteSizeLong()));
677
678 PostProcessing(keep_initialized_, post_processors_, any, &random_)
Vitaly Buka4b3d7832020-01-29 00:34:12 -0800679 .Run(message2, kMaxInitializeDepth);
680 assert(IsInitialized(*message2));
681}
682
Vitaly Bukad3600272020-01-26 23:24:10 -0800683void Mutator::RegisterPostProcessor(const Descriptor* desc,
Peter Foleyfe76ed62019-09-30 17:03:37 -0700684 PostProcess callback) {
685 post_processors_.emplace(desc, callback);
686}
687
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800688bool Mutator::MutateImpl(const ConstMessages& sources, const Messages& messages,
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800689 bool copy_clone_only, int size_increase_hint) {
Vitaly Bukac1839912020-01-26 22:32:57 -0800690 MutationBitset mutations;
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800691 if (copy_clone_only) {
692 mutations[static_cast<size_t>(Mutation::Copy)] = true;
693 mutations[static_cast<size_t>(Mutation::Clone)] = true;
694 } else if (size_increase_hint <= 16) {
Vitaly Bukac1839912020-01-26 22:32:57 -0800695 mutations[static_cast<size_t>(Mutation::Delete)] = true;
696 } else {
697 mutations.set();
Vitaly Bukadfd73df2020-02-04 12:00:21 -0800698 mutations[static_cast<size_t>(Mutation::Copy)] = false;
699 mutations[static_cast<size_t>(Mutation::Clone)] = false;
Vitaly Bukac1839912020-01-26 22:32:57 -0800700 }
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800701 while (mutations.any()) {
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800702 MutationSampler mutation(keep_initialized_, mutations, &random_);
703 for (Message* message : messages) mutation.Sample(message);
704
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700705 switch (mutation.mutation()) {
706 case Mutation::None:
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800707 return true;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700708 case Mutation::Add:
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800709 CreateField()(mutation.field(), size_increase_hint, sources, this);
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800710 return true;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700711 case Mutation::Mutate:
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800712 MutateField()(mutation.field(), size_increase_hint, sources, this);
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800713 return true;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700714 case Mutation::Delete:
715 DeleteField()(mutation.field());
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800716 return true;
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800717 case Mutation::Clone: {
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800718 CreateDefaultField()(mutation.field());
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800719 DataSourceSampler source_sampler(mutation.field(), &random_,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800720 size_increase_hint);
721 for (const Message* source : sources) source_sampler.Sample(*source);
Vitaly Buka1989ccb2020-02-04 15:40:30 -0800722 if (source_sampler.IsEmpty()) {
723 if (!IsProto3SimpleField(*mutation.field().descriptor()))
724 return true; // CreateField is enough for proto2.
725 break;
726 }
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800727 CopyField()(source_sampler.field(), mutation.field());
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800728 return true;
Vitaly Buka5635a7a2020-01-26 01:52:40 -0800729 }
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700730 case Mutation::Copy: {
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800731 DataSourceSampler source_sampler(mutation.field(), &random_,
Vitaly Bukaf62086c2020-01-29 01:11:23 -0800732 size_increase_hint);
733 for (const Message* source : sources) source_sampler.Sample(*source);
Vitaly Buka0f63f912020-01-24 15:02:45 -0800734 if (source_sampler.IsEmpty()) break;
735 CopyField()(source_sampler.field(), mutation.field());
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800736 return true;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700737 }
738 default:
739 assert(false && "unexpected mutation");
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800740 return false;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700741 }
Vitaly Buka1989ccb2020-02-04 15:40:30 -0800742
743 // Don't try same mutation next time.
744 mutations[static_cast<size_t>(mutation.mutation())] = false;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700745 }
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800746 return false;
Vitaly Buka3183b0d2019-09-06 15:11:10 -0700747}
748
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700749int32_t Mutator::MutateInt32(int32_t value) { return FlipBit(value, &random_); }
Vitaly Bukae79e0182017-03-01 16:02:14 -0800750
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700751int64_t Mutator::MutateInt64(int64_t value) { return FlipBit(value, &random_); }
Vitaly Bukae79e0182017-03-01 16:02:14 -0800752
753uint32_t Mutator::MutateUInt32(uint32_t value) {
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700754 return FlipBit(value, &random_);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800755}
756
Vitaly Bukae79e0182017-03-01 16:02:14 -0800757uint64_t Mutator::MutateUInt64(uint64_t value) {
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700758 return FlipBit(value, &random_);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800759}
760
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700761float Mutator::MutateFloat(float value) { return FlipBit(value, &random_); }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800762
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700763double Mutator::MutateDouble(double value) { return FlipBit(value, &random_); }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800764
Vitaly Bukae79e0182017-03-01 16:02:14 -0800765bool Mutator::MutateBool(bool value) { return !value; }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800766
Vitaly Bukae79e0182017-03-01 16:02:14 -0800767size_t Mutator::MutateEnum(size_t index, size_t item_count) {
Vitaly Bukaee1c76a2017-03-15 10:48:53 -0700768 if (item_count <= 1) return 0;
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700769 return (index + 1 + GetRandomIndex(&random_, item_count - 1)) % item_count;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800770}
771
Vitaly Bukae79e0182017-03-01 16:02:14 -0800772std::string Mutator::MutateString(const std::string& value,
Vitaly Buka1c91e722020-01-25 21:56:22 -0800773 int size_increase_hint) {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800774 std::string result = value;
Vitaly Buka5d013202017-02-24 16:50:11 -0800775
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700776 while (!result.empty() && GetRandomBool(&random_)) {
777 result.erase(GetRandomIndex(&random_, result.size()), 1);
Vitaly Buka432b5452016-12-09 14:42:09 -0800778 }
779
Vitaly Buka1c91e722020-01-25 21:56:22 -0800780 while (size_increase_hint > 0 &&
781 result.size() < static_cast<size_t>(size_increase_hint) &&
782 GetRandomBool(&random_)) {
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700783 size_t index = GetRandomIndex(&random_, result.size() + 1);
784 result.insert(result.begin() + index, GetRandomIndex(&random_, 1 << 8));
Vitaly Buka432b5452016-12-09 14:42:09 -0800785 }
786
Vitaly Bukac020de12017-03-03 19:36:23 -0800787 if (result != value) return result;
788
789 if (result.empty()) {
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700790 result.push_back(GetRandomIndex(&random_, 1 << 8));
Vitaly Bukac020de12017-03-03 19:36:23 -0800791 return result;
792 }
793
Vitaly Buka4af611d2016-12-03 18:57:32 -0800794 if (!result.empty())
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700795 FlipBit(result.size(), reinterpret_cast<uint8_t*>(&result[0]), &random_);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800796 return result;
797}
Vitaly Buka432b5452016-12-09 14:42:09 -0800798
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700799std::string Mutator::MutateUtf8String(const std::string& value,
Vitaly Buka1c91e722020-01-25 21:56:22 -0800800 int size_increase_hint) {
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700801 std::string str = MutateString(value, size_increase_hint);
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700802 FixUtf8String(&str, &random_);
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700803 return str;
804}
805
Vitaly Buka9eaf0632020-01-15 17:30:20 -0800806bool Mutator::IsInitialized(const Message& message) const {
807 if (!keep_initialized_ || message.IsInitialized()) return true;
808 std::cerr << "Uninitialized: " << message.DebugString() << "\n";
809 return false;
810}
811
Vitaly Buka432b5452016-12-09 14:42:09 -0800812} // namespace protobuf_mutator