blob: df493717f313ad9caa05e50332c41612ceb0e75d [file] [log] [blame]
Vitaly Buka00b61072016-10-19 23:22:511// 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 23:46:5815#include "src/mutator.h"
Vitaly Buka00b61072016-10-19 23:22:5116
Vitaly Buka781853c2016-11-22 07:09:3517#include <algorithm>
Vitaly Bukac1839912020-01-27 06:32:5718#include <bitset>
Vitaly Buka0e17fd72016-11-18 18:02:4619#include <map>
Vitaly Bukadbc4c0f2020-01-29 09:22:2120#include <memory>
Vitaly Buka781853c2016-11-22 07:09:3521#include <random>
Vitaly Buka0e17fd72016-11-18 18:02:4622#include <string>
Allen-Webbc4fa5912018-09-07 22:53:3023#include <vector>
Vitaly Buka00b61072016-10-19 23:22:5124
Vitaly Buka9dd2f8e2017-01-13 08:48:3125#include "src/field_instance.h"
Vitaly Bukaaf8136f2017-06-09 23:40:1226#include "src/utf8_fix.h"
Vitaly Buka9dd2f8e2017-01-13 08:48:3127#include "src/weighted_reservoir_sampler.h"
Vitaly Buka00b61072016-10-19 23:22:5128
Vitaly Bukaf86815c2017-02-27 22:19:1929namespace protobuf_mutator {
30
Vitaly Bukadbc4c0f2020-01-29 09:22:2131using protobuf::Any;
Vitaly Buka6c6dbbe2017-02-22 21:58:2432using protobuf::Descriptor;
Vitaly Buka6c6dbbe2017-02-22 21:58:2433using protobuf::FieldDescriptor;
Vitaly Buka796b1122017-03-03 22:42:0234using protobuf::FileDescriptor;
Vitaly Buka6c6dbbe2017-02-22 21:58:2435using protobuf::Message;
36using protobuf::OneofDescriptor;
37using protobuf::Reflection;
Vitaly Buka4782c142017-03-04 08:12:3238using protobuf::util::MessageDifferencer;
Vitaly Buka796b1122017-03-03 22:42:0239using std::placeholders::_1;
Vitaly Buka0e17fd72016-11-18 18:02:4640
41namespace {
42
Vitaly Bukae4eae602017-09-29 00:28:1243const int kMaxInitializeDepth = 200;
Vitaly Buka329fa462017-03-15 23:52:1744const uint64_t kDefaultMutateWeight = 1000000;
Vitaly Buka0e17fd72016-11-18 18:02:4645
Vitaly Bukac1839912020-01-27 06:32:5746enum class Mutation : uint8_t {
Vitaly Buka30de3092016-11-18 19:39:0747 None,
Vitaly Buka4af611d2016-12-04 02:57:3248 Add, // Adds new field with default value.
49 Mutate, // Mutates field contents.
50 Delete, // Deletes field.
Vitaly Bukaa3e59c72016-12-07 00:53:5651 Copy, // Copy values copied from another field.
Vitaly Buka5635a7a2020-01-26 09:52:4052 Clone, // Create new field with value copied from another.
Vitaly Bukac1839912020-01-27 06:32:5753
54 Last = Clone,
Vitaly Buka0e17fd72016-11-18 18:02:4655};
56
Vitaly Bukac1839912020-01-27 06:32:5757using MutationBitset = std::bitset<static_cast<size_t>(Mutation::Last)>;
58
Vitaly Bukaf62086c2020-01-29 09:11:2359using Messages = std::vector<Message*>;
60using ConstMessages = std::vector<const Message*>;
61
Vitaly Bukab592ff02017-03-03 22:35:5262// Return random integer from [0, count)
Vitaly Bukaf62fe472017-03-02 07:05:1563size_t GetRandomIndex(RandomEngine* random, size_t count) {
Vitaly Bukab592ff02017-03-03 22:35:5264 assert(count > 0);
65 if (count == 1) return 0;
66 return std::uniform_int_distribution<size_t>(0, count - 1)(*random);
67}
68
Vitaly Buka4af611d2016-12-04 02:57:3269// Flips random bit in the buffer.
Vitaly Bukaf62fe472017-03-02 07:05:1570void FlipBit(size_t size, uint8_t* bytes, RandomEngine* random) {
Vitaly Bukab592ff02017-03-03 22:35:5271 size_t bit = GetRandomIndex(random, size * 8);
Vitaly Buka4af611d2016-12-04 02:57:3272 bytes[bit / 8] ^= (1u << (bit % 8));
73}
Vitaly Buka781853c2016-11-22 07:09:3574
Vitaly Buka4af611d2016-12-04 02:57:3275// Flips random bit in the value.
76template <class T>
Vitaly Bukaf62fe472017-03-02 07:05:1577T FlipBit(T value, RandomEngine* random) {
Vitaly Buka4af611d2016-12-04 02:57:3278 FlipBit(sizeof(value), reinterpret_cast<uint8_t*>(&value), random);
79 return value;
80}
Vitaly Buka781853c2016-11-22 07:09:3581
Vitaly Bukabeb90802017-02-28 23:28:1082// Return true with probability about 1-of-n.
Vitaly Bukaf62fe472017-03-02 07:05:1583bool GetRandomBool(RandomEngine* random, size_t n = 2) {
Vitaly Bukabeb90802017-02-28 23:28:1084 return GetRandomIndex(random, n) == 0;
85}
86
Vitaly Buka28ca0ee2017-03-05 05:35:4287bool IsProto3SimpleField(const FieldDescriptor& field) {
88 assert(field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
89 field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2);
90 return field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
91 field.cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
92 !field.containing_oneof() && !field.is_repeated();
93}
94
Vitaly Bukad4ab1e72017-03-04 07:51:1995struct CreateDefaultField : public FieldFunction<CreateDefaultField> {
Vitaly Buka91ad7b02016-12-12 23:41:4196 template <class T>
Vitaly Bukad4ab1e72017-03-04 07:51:1997 void ForType(const FieldInstance& field) const {
Vitaly Buka91ad7b02016-12-12 23:41:4198 T value;
99 field.GetDefault(&value);
100 field.Create(value);
Vitaly Bukabec52222016-12-09 22:29:32101 }
Vitaly Buka91ad7b02016-12-12 23:41:41102};
Vitaly Bukabec52222016-12-09 22:29:32103
Vitaly Bukad4ab1e72017-03-04 07:51:19104struct DeleteField : public FieldFunction<DeleteField> {
Vitaly Buka91ad7b02016-12-12 23:41:41105 template <class T>
Vitaly Bukad4ab1e72017-03-04 07:51:19106 void ForType(const FieldInstance& field) const {
Vitaly Buka91ad7b02016-12-12 23:41:41107 field.Delete();
Vitaly Bukabec52222016-12-09 22:29:32108 }
Vitaly Bukabec52222016-12-09 22:29:32109};
110
Vitaly Bukad4ab1e72017-03-04 07:51:19111struct CopyField : public FieldFunction<CopyField> {
Vitaly Bukaa3e59c72016-12-07 00:53:56112 template <class T>
Vitaly Bukad4ab1e72017-03-04 07:51:19113 void ForType(const ConstFieldInstance& source,
114 const FieldInstance& field) const {
Vitaly Bukaa3e59c72016-12-07 00:53:56115 T value;
116 source.Load(&value);
117 field.Store(value);
118 }
Vitaly Bukaa3e59c72016-12-07 00:53:56119};
120
Vitaly Bukad4ab1e72017-03-04 07:51:19121struct AppendField : public FieldFunction<AppendField> {
Vitaly Bukaadfc27c2017-02-27 06:36:36122 template <class T>
Vitaly Bukad4ab1e72017-03-04 07:51:19123 void ForType(const ConstFieldInstance& source,
124 const FieldInstance& field) const {
Vitaly Bukaadfc27c2017-02-27 06:36:36125 T value;
126 source.Load(&value);
127 field.Create(value);
128 }
Vitaly Bukaadfc27c2017-02-27 06:36:36129};
130
Vitaly Buka2792ed72019-01-23 19:04:24131class CanCopyAndDifferentField
132 : public FieldFunction<CanCopyAndDifferentField, bool> {
Vitaly Buka4782c142017-03-04 08:12:32133 public:
134 template <class T>
Vitaly Buka5cd166e2020-01-26 06:33:05135 bool ForType(const ConstFieldInstance& src, const ConstFieldInstance& dst,
136 int size_increase_hint) const {
Vitaly Buka2792ed72019-01-23 19:04:24137 T s;
138 src.Load(&s);
139 if (!dst.CanStore(s)) return false;
140 T d;
141 dst.Load(&d);
Vitaly Buka5cd166e2020-01-26 06:33:05142 return SizeDiff(s, d) <= size_increase_hint && !IsEqual(s, d);
Vitaly Buka4782c142017-03-04 08:12:32143 }
144
145 private:
146 bool IsEqual(const ConstFieldInstance::Enum& a,
147 const ConstFieldInstance::Enum& b) const {
148 assert(a.count == b.count);
149 return a.index == b.index;
150 }
151
Vitaly Bukad3600272020-01-27 07:24:10152 bool IsEqual(const std::unique_ptr<Message>& a,
153 const std::unique_ptr<Message>& b) const {
Vitaly Buka4782c142017-03-04 08:12:32154 return MessageDifferencer::Equals(*a, *b);
155 }
156
157 template <class T>
158 bool IsEqual(const T& a, const T& b) const {
159 return a == b;
160 }
Vitaly Buka5cd166e2020-01-26 06:33:05161
Vitaly Bukad3600272020-01-27 07:24:10162 int64_t SizeDiff(const std::unique_ptr<Message>& src,
163 const std::unique_ptr<Message>& dst) const {
Vitaly Buka5cd166e2020-01-26 06:33:05164 return src->ByteSizeLong() - dst->ByteSizeLong();
165 }
166
167 int64_t SizeDiff(const std::string& src, const std::string& dst) const {
168 return src.size() - dst.size();
169 }
170
171 template <class T>
172 int64_t SizeDiff(const T&, const T&) const {
173 return 0;
174 }
Vitaly Buka4782c142017-03-04 08:12:32175};
176
Vitaly Buka4af611d2016-12-04 02:57:32177// Selects random field and mutation from the given proto message.
Vitaly Buka781853c2016-11-22 07:09:35178class MutationSampler {
Vitaly Bukac9d22482016-11-21 21:29:17179 public:
Vitaly Bukac1839912020-01-27 06:32:57180 MutationSampler(bool keep_initialized, MutationBitset allowed_mutations,
Vitaly Bukaf62086c2020-01-29 09:11:23181 RandomEngine* random)
Vitaly Buka4908d252020-01-25 03:10:34182 : keep_initialized_(keep_initialized),
Vitaly Bukac1839912020-01-27 06:32:57183 allowed_mutations_(allowed_mutations),
Vitaly Buka4908d252020-01-25 03:10:34184 random_(random),
Vitaly Bukaf62086c2020-01-29 09:11:23185 sampler_(random) {}
Vitaly Bukac9d22482016-11-21 21:29:17186
Vitaly Buka4af611d2016-12-04 02:57:32187 // Returns selected field.
Vitaly Bukabec52222016-12-09 22:29:32188 const FieldInstance& field() const { return sampler_.selected().field; }
Vitaly Buka4af611d2016-12-04 02:57:32189
190 // Returns selected mutation.
Vitaly Buka432b5452016-12-09 22:42:09191 Mutation mutation() const { return sampler_.selected().mutation; }
Vitaly Buka4af611d2016-12-04 02:57:32192
Vitaly Buka781853c2016-11-22 07:09:35193 void Sample(Message* message) {
Vitaly Bukaf62086c2020-01-29 09:11:23194 SampleImpl(message);
195 assert(mutation() != Mutation::None ||
196 !allowed_mutations_[static_cast<size_t>(Mutation::Mutate)] ||
197 message->GetDescriptor()->field_count() == 0);
198 }
199
200 private:
201 void SampleImpl(Message* message) {
Vitaly Buka781853c2016-11-22 07:09:35202 const Descriptor* descriptor = message->GetDescriptor();
203 const Reflection* reflection = message->GetReflection();
204
205 int field_count = descriptor->field_count();
206 for (int i = 0; i < field_count; ++i) {
207 const FieldDescriptor* field = descriptor->field(i);
208 if (const OneofDescriptor* oneof = field->containing_oneof()) {
209 // Handle entire oneof group on the first field.
210 if (field->index_in_oneof() == 0) {
Vitaly Buka2f660a52017-03-04 03:46:14211 assert(oneof->field_count());
212 const FieldDescriptor* current_field =
213 reflection->GetOneofFieldDescriptor(*message, oneof);
214 for (;;) {
215 const FieldDescriptor* add_field =
216 oneof->field(GetRandomIndex(random_, oneof->field_count()));
217 if (add_field != current_field) {
Vitaly Buka4908d252020-01-25 03:10:34218 Try({message, add_field}, Mutation::Add);
Vitaly Buka5635a7a2020-01-26 09:52:40219 Try({message, add_field}, Mutation::Clone);
Vitaly Buka2f660a52017-03-04 03:46:14220 break;
221 }
222 if (oneof->field_count() < 2) break;
223 }
224 if (current_field) {
Vitaly Buka4908d252020-01-25 03:10:34225 if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
226 Try({message, current_field}, Mutation::Mutate);
227 Try({message, current_field}, Mutation::Delete);
228 Try({message, current_field}, Mutation::Copy);
Vitaly Buka781853c2016-11-22 07:09:35229 }
230 }
231 } else {
232 if (field->is_repeated()) {
Vitaly Bukabec52222016-12-09 22:29:32233 int field_size = reflection->FieldSize(*message, field);
Vitaly Buka5635a7a2020-01-26 09:52:40234 size_t random_index = GetRandomIndex(random_, field_size + 1);
235 Try({message, field, random_index}, Mutation::Add);
236 Try({message, field, random_index}, Mutation::Clone);
Vitaly Buka781853c2016-11-22 07:09:35237
Vitaly Bukabec52222016-12-09 22:29:32238 if (field_size) {
239 size_t random_index = GetRandomIndex(random_, field_size);
Vitaly Buka4908d252020-01-25 03:10:34240 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
241 Try({message, field, random_index}, Mutation::Mutate);
242 Try({message, field, random_index}, Mutation::Delete);
243 Try({message, field, random_index}, Mutation::Copy);
Vitaly Buka781853c2016-11-22 07:09:35244 }
245 } else {
Vitaly Buka28ca0ee2017-03-05 05:35:42246 if (reflection->HasField(*message, field) ||
247 IsProto3SimpleField(*field)) {
Vitaly Buka4908d252020-01-25 03:10:34248 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
249 Try({message, field}, Mutation::Mutate);
Vitaly Buka28ca0ee2017-03-05 05:35:42250 if (!IsProto3SimpleField(*field) &&
251 (!field->is_required() || !keep_initialized_)) {
Vitaly Buka4908d252020-01-25 03:10:34252 Try({message, field}, Mutation::Delete);
Vitaly Buka28ca0ee2017-03-05 05:35:42253 }
Vitaly Buka4908d252020-01-25 03:10:34254 Try({message, field}, Mutation::Copy);
Vitaly Buka781853c2016-11-22 07:09:35255 } else {
Vitaly Buka4908d252020-01-25 03:10:34256 Try({message, field}, Mutation::Add);
Vitaly Buka5635a7a2020-01-26 09:52:40257 Try({message, field}, Mutation::Clone);
Vitaly Buka781853c2016-11-22 07:09:35258 }
259 }
260 }
261
262 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
263 if (field->is_repeated()) {
264 const int field_size = reflection->FieldSize(*message, field);
265 for (int j = 0; j < field_size; ++j)
Vitaly Bukaf62086c2020-01-29 09:11:23266 SampleImpl(reflection->MutableRepeatedMessage(message, field, j));
Vitaly Buka781853c2016-11-22 07:09:35267 } else if (reflection->HasField(*message, field)) {
Vitaly Bukaf62086c2020-01-29 09:11:23268 SampleImpl(reflection->MutableMessage(message, field));
Vitaly Buka781853c2016-11-22 07:09:35269 }
270 }
271 }
272 }
273
Vitaly Buka4908d252020-01-25 03:10:34274 void Try(const FieldInstance& field, Mutation mutation) {
275 assert(mutation != Mutation::None);
Vitaly Bukac1839912020-01-27 06:32:57276 if (!allowed_mutations_[static_cast<size_t>(mutation)]) return;
Vitaly Buka4908d252020-01-25 03:10:34277 sampler_.Try(kDefaultMutateWeight, {field, mutation});
278 }
279
Vitaly Buka781853c2016-11-22 07:09:35280 bool keep_initialized_ = false;
Vitaly Bukac1839912020-01-27 06:32:57281 MutationBitset allowed_mutations_;
Vitaly Buka4af611d2016-12-04 02:57:32282
Vitaly Bukaf62fe472017-03-02 07:05:15283 RandomEngine* random_;
Vitaly Buka4af611d2016-12-04 02:57:32284
285 struct Result {
Vitaly Buka91ad7b02016-12-12 23:41:41286 Result() = default;
Vitaly Bukabec52222016-12-09 22:29:32287 Result(const FieldInstance& f, Mutation m) : field(f), mutation(m) {}
Vitaly Buka91ad7b02016-12-12 23:41:41288
Vitaly Bukabec52222016-12-09 22:29:32289 FieldInstance field;
290 Mutation mutation = Mutation::None;
Vitaly Buka4af611d2016-12-04 02:57:32291 };
Vitaly Bukaf62fe472017-03-02 07:05:15292 WeightedReservoirSampler<Result, RandomEngine> sampler_;
Vitaly Bukac9d22482016-11-21 21:29:17293};
294
Vitaly Bukaa3e59c72016-12-07 00:53:56295// Selects random field of compatible type to use for clone mutations.
296class DataSourceSampler {
297 public:
Vitaly Bukaf62fe472017-03-02 07:05:15298 DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random,
Vitaly Bukaf62086c2020-01-29 09:11:23299 int size_increase_hint)
Vitaly Buka5cd166e2020-01-26 06:33:05300 : match_(match),
301 random_(random),
302 size_increase_hint_(size_increase_hint),
Vitaly Bukaf62086c2020-01-29 09:11:23303 sampler_(random) {}
304
305 void Sample(const Message& message) { SampleImpl(message); }
Vitaly Bukaa3e59c72016-12-07 00:53:56306
307 // Returns selected field.
Vitaly Buka88712862017-02-27 06:21:30308 const ConstFieldInstance& field() const {
Vitaly Buka72019dc2016-12-15 03:17:24309 assert(!IsEmpty());
310 return sampler_.selected();
311 }
312
313 bool IsEmpty() const { return sampler_.IsEmpty(); }
Vitaly Bukaa3e59c72016-12-07 00:53:56314
315 private:
Vitaly Bukaf62086c2020-01-29 09:11:23316 void SampleImpl(const Message& message) {
Vitaly Buka0f63f912020-01-24 23:02:45317 const Descriptor* descriptor = message.GetDescriptor();
318 const Reflection* reflection = message.GetReflection();
Vitaly Bukaa3e59c72016-12-07 00:53:56319
320 int field_count = descriptor->field_count();
321 for (int i = 0; i < field_count; ++i) {
322 const FieldDescriptor* field = descriptor->field(i);
323 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
324 if (field->is_repeated()) {
Vitaly Buka0f63f912020-01-24 23:02:45325 const int field_size = reflection->FieldSize(message, field);
Vitaly Bukaa3e59c72016-12-07 00:53:56326 for (int j = 0; j < field_size; ++j) {
Vitaly Bukaf62086c2020-01-29 09:11:23327 SampleImpl(reflection->GetRepeatedMessage(message, field, j));
Vitaly Bukaa3e59c72016-12-07 00:53:56328 }
Vitaly Buka0f63f912020-01-24 23:02:45329 } else if (reflection->HasField(message, field)) {
Vitaly Bukaf62086c2020-01-29 09:11:23330 SampleImpl(reflection->GetMessage(message, field));
Vitaly Bukaa3e59c72016-12-07 00:53:56331 }
332 }
333
334 if (field->cpp_type() != match_.cpp_type()) continue;
335 if (match_.cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
336 if (field->enum_type() != match_.enum_type()) continue;
337 } else if (match_.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
338 if (field->message_type() != match_.message_type()) continue;
339 }
340
Vitaly Bukaa3e59c72016-12-07 00:53:56341 if (field->is_repeated()) {
Vitaly Buka0f63f912020-01-24 23:02:45342 if (int field_size = reflection->FieldSize(message, field)) {
343 ConstFieldInstance source(&message, field,
Vitaly Buka4782c142017-03-04 08:12:32344 GetRandomIndex(random_, field_size));
Vitaly Buka5cd166e2020-01-26 06:33:05345 if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
Vitaly Buka4782c142017-03-04 08:12:32346 sampler_.Try(field_size, source);
Vitaly Bukaa3e59c72016-12-07 00:53:56347 }
348 } else {
Vitaly Buka0f63f912020-01-24 23:02:45349 if (reflection->HasField(message, field)) {
350 ConstFieldInstance source(&message, field);
Vitaly Buka5cd166e2020-01-26 06:33:05351 if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
Vitaly Buka2792ed72019-01-23 19:04:24352 sampler_.Try(1, source);
Vitaly Bukaa3e59c72016-12-07 00:53:56353 }
354 }
355 }
356 }
357
Vitaly Buka88712862017-02-27 06:21:30358 ConstFieldInstance match_;
Vitaly Bukaf62fe472017-03-02 07:05:15359 RandomEngine* random_;
Vitaly Buka5cd166e2020-01-26 06:33:05360 int size_increase_hint_;
Vitaly Bukaa3e59c72016-12-07 00:53:56361
Vitaly Bukaf62fe472017-03-02 07:05:15362 WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_;
Vitaly Bukaa3e59c72016-12-07 00:53:56363};
364
Vitaly Bukadbc4c0f2020-01-29 09:22:21365using UnpackedAny =
366 std::unordered_map<const Message*, std::unique_ptr<Message>>;
367
368const Descriptor* GetAnyTypeDescriptor(const Any& any) {
369 std::string type_name;
370 if (!Any::ParseAnyTypeUrl(any.type_url(), &type_name)) return nullptr;
371 return any.descriptor()->file()->pool()->FindMessageTypeByName(type_name);
372}
373
374std::unique_ptr<Message> UnpackAny(const Any& any) {
375 const Descriptor* desc = GetAnyTypeDescriptor(any);
376 if (!desc) return {};
377 std::unique_ptr<Message> message(
378 any.GetReflection()->GetMessageFactory()->GetPrototype(desc)->New());
379 message->ParsePartialFromString(any.value());
380 return message;
381}
382
383const Any* CastToAny(const Message* message) {
384 return Any::GetDescriptor() == message->GetDescriptor()
385 ? static_cast<const Any*>(message)
386 : nullptr;
387}
388
389Any* CastToAny(Message* message) {
390 return Any::GetDescriptor() == message->GetDescriptor()
391 ? static_cast<Any*>(message)
392 : nullptr;
393}
394
395std::unique_ptr<Message> UnpackIfAny(const Message& message) {
396 if (const Any* any = CastToAny(&message)) return UnpackAny(*any);
397 return {};
398}
399
400void UnpackAny(const Message& message, UnpackedAny* result) {
401 if (std::unique_ptr<Message> any = UnpackIfAny(message)) {
402 UnpackAny(*any, result);
403 result->emplace(&message, std::move(any));
404 return;
405 }
406
407 const Descriptor* descriptor = message.GetDescriptor();
408 const Reflection* reflection = message.GetReflection();
409
410 for (int i = 0; i < descriptor->field_count(); ++i) {
411 const FieldDescriptor* field = descriptor->field(i);
412 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
413 if (field->is_repeated()) {
414 const int field_size = reflection->FieldSize(message, field);
415 for (int j = 0; j < field_size; ++j) {
416 UnpackAny(reflection->GetRepeatedMessage(message, field, j), result);
417 }
418 } else if (reflection->HasField(message, field)) {
419 UnpackAny(reflection->GetMessage(message, field), result);
420 }
421 }
422 }
423}
424
Vitaly Buka045acda2020-01-29 08:26:35425class PostProcessing {
426 public:
Vitaly Bukaf62086c2020-01-29 09:11:23427 using PostProcessors =
428 std::unordered_multimap<const Descriptor*, Mutator::PostProcess>;
Vitaly Buka045acda2020-01-29 08:26:35429
430 PostProcessing(bool keep_initialized, const PostProcessors& post_processors,
Vitaly Bukadbc4c0f2020-01-29 09:22:21431 UnpackedAny& any, RandomEngine* random)
Vitaly Buka045acda2020-01-29 08:26:35432 : keep_initialized_(keep_initialized),
433 post_processors_(post_processors),
Vitaly Bukadbc4c0f2020-01-29 09:22:21434 any_(any),
Vitaly Buka045acda2020-01-29 08:26:35435 random_(random) {}
436
437 void Run(Message* message, int max_depth) {
438 --max_depth;
439 const Descriptor* descriptor = message->GetDescriptor();
440
441 // Apply custom mutators in nested messages before packing any.
442 const Reflection* reflection = message->GetReflection();
443 for (int i = 0; i < descriptor->field_count(); i++) {
444 const FieldDescriptor* field = descriptor->field(i);
445 if (keep_initialized_ &&
446 (field->is_required() || descriptor->options().map_entry()) &&
447 !reflection->HasField(*message, field)) {
448 CreateDefaultField()(FieldInstance(message, field));
449 }
450
451 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
452
453 if (max_depth < 0 && !field->is_required()) {
454 // Clear deep optional fields to avoid stack overflow.
455 reflection->ClearField(message, field);
456 if (field->is_repeated())
457 assert(!reflection->FieldSize(*message, field));
458 else
459 assert(!reflection->HasField(*message, field));
460 continue;
461 }
462
463 if (field->is_repeated()) {
464 const int field_size = reflection->FieldSize(*message, field);
465 for (int j = 0; j < field_size; ++j) {
466 Message* nested_message =
467 reflection->MutableRepeatedMessage(message, field, j);
468 Run(nested_message, max_depth);
469 }
470 } else if (reflection->HasField(*message, field)) {
471 Message* nested_message = reflection->MutableMessage(message, field);
472 Run(nested_message, max_depth);
473 }
474 }
475
Vitaly Bukadbc4c0f2020-01-29 09:22:21476 if (Any* any = CastToAny(message)) {
477 if (max_depth < 0) {
478 // Clear deep Any fields to avoid stack overflow.
479 any->Clear();
480 } else {
481 auto It = any_.find(message);
482 if (It != any_.end()) {
483 Run(It->second.get(), max_depth);
484 // assert(GetAnyTypeDescriptor(*any) == It->second->GetDescriptor());
485 // if (GetAnyTypeDescriptor(*any) != It->second->GetDescriptor()) {}
486 It->second->SerializePartialToString(any->mutable_value());
487 }
488 }
489 }
490
491 // Call user callback after message trimmed, initialized and packed.
Vitaly Buka045acda2020-01-29 08:26:35492 auto range = post_processors_.equal_range(descriptor);
493 for (auto it = range.first; it != range.second; ++it)
494 it->second(message, (*random_)());
495 }
496
497 private:
498 bool keep_initialized_;
499 const PostProcessors& post_processors_;
Vitaly Bukadbc4c0f2020-01-29 09:22:21500 UnpackedAny& any_;
Vitaly Buka045acda2020-01-29 08:26:35501 RandomEngine* random_;
502};
503
Vitaly Buka0e17fd72016-11-18 18:02:46504} // namespace
505
Vitaly Buka5d013202017-02-25 00:50:11506class FieldMutator {
Vitaly Buka432b5452016-12-09 22:42:09507 public:
Vitaly Buka1c91e722020-01-26 05:56:22508 FieldMutator(int size_increase_hint, bool enforce_changes,
Vitaly Bukaf62086c2020-01-29 09:11:23509 bool enforce_utf8_strings, const ConstMessages& sources,
Vitaly Buka0f63f912020-01-24 23:02:45510 Mutator* mutator)
Vitaly Buka0e9439f2017-03-16 00:51:57511 : size_increase_hint_(size_increase_hint),
512 enforce_changes_(enforce_changes),
Vitaly Bukaaf8136f2017-06-09 23:40:12513 enforce_utf8_strings_(enforce_utf8_strings),
Vitaly Bukaf62086c2020-01-29 09:11:23514 sources_(sources),
Vitaly Buka0e9439f2017-03-16 00:51:57515 mutator_(mutator) {}
Vitaly Buka91ad7b02016-12-12 23:41:41516
Vitaly Buka796b1122017-03-03 22:42:02517 void Mutate(int32_t* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14518 RepeatMutate(value, std::bind(&Mutator::MutateInt32, mutator_, _1));
Vitaly Buka796b1122017-03-03 22:42:02519 }
Vitaly Buka91ad7b02016-12-12 23:41:41520
Vitaly Buka796b1122017-03-03 22:42:02521 void Mutate(int64_t* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14522 RepeatMutate(value, std::bind(&Mutator::MutateInt64, mutator_, _1));
Vitaly Buka796b1122017-03-03 22:42:02523 }
Vitaly Buka91ad7b02016-12-12 23:41:41524
525 void Mutate(uint32_t* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14526 RepeatMutate(value, std::bind(&Mutator::MutateUInt32, mutator_, _1));
Vitaly Buka91ad7b02016-12-12 23:41:41527 }
528
529 void Mutate(uint64_t* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14530 RepeatMutate(value, std::bind(&Mutator::MutateUInt64, mutator_, _1));
Vitaly Buka91ad7b02016-12-12 23:41:41531 }
532
Vitaly Buka796b1122017-03-03 22:42:02533 void Mutate(float* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14534 RepeatMutate(value, std::bind(&Mutator::MutateFloat, mutator_, _1));
Vitaly Buka796b1122017-03-03 22:42:02535 }
Vitaly Buka91ad7b02016-12-12 23:41:41536
Vitaly Buka796b1122017-03-03 22:42:02537 void Mutate(double* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14538 RepeatMutate(value, std::bind(&Mutator::MutateDouble, mutator_, _1));
Vitaly Buka796b1122017-03-03 22:42:02539 }
Vitaly Buka91ad7b02016-12-12 23:41:41540
Vitaly Buka796b1122017-03-03 22:42:02541 void Mutate(bool* value) const {
Vitaly Bukad7f943f2019-01-31 22:05:33542 RepeatMutate(value, std::bind(&Mutator::MutateBool, mutator_, _1));
Vitaly Buka796b1122017-03-03 22:42:02543 }
Vitaly Buka91ad7b02016-12-12 23:41:41544
545 void Mutate(FieldInstance::Enum* value) const {
Vitaly Bukae79e0182017-03-02 00:02:14546 RepeatMutate(&value->index,
Vitaly Bukad7f943f2019-01-31 22:05:33547 std::bind(&Mutator::MutateEnum, mutator_, _1, value->count));
Vitaly Buka91ad7b02016-12-12 23:41:41548 assert(value->index < value->count);
549 }
550
551 void Mutate(std::string* value) const {
Vitaly Bukaaf8136f2017-06-09 23:40:12552 if (enforce_utf8_strings_) {
553 RepeatMutate(value, std::bind(&Mutator::MutateUtf8String, mutator_, _1,
554 size_increase_hint_));
555 } else {
556 RepeatMutate(value, std::bind(&Mutator::MutateString, mutator_, _1,
557 size_increase_hint_));
558 }
Vitaly Buka91ad7b02016-12-12 23:41:41559 }
560
Vitaly Bukab2c4fb52017-03-16 18:50:40561 void Mutate(std::unique_ptr<Message>* message) const {
562 assert(!enforce_changes_);
563 assert(*message);
Vitaly Bukad7f943f2019-01-31 22:05:33564 if (GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_))
565 return;
Vitaly Bukaf62086c2020-01-29 09:11:23566 mutator_->MutateImpl(sources_, {message->get()}, false,
567 size_increase_hint_);
Vitaly Bukab2c4fb52017-03-16 18:50:40568 }
Vitaly Buka432b5452016-12-09 22:42:09569
Vitaly Buka5d013202017-02-25 00:50:11570 private:
Vitaly Buka796b1122017-03-03 22:42:02571 template <class T, class F>
Vitaly Bukad7f943f2019-01-31 22:05:33572 void RepeatMutate(T* value, F mutate) const {
Vitaly Buka0e9439f2017-03-16 00:51:57573 if (!enforce_changes_ &&
Vitaly Bukad7f943f2019-01-31 22:05:33574 GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_)) {
Vitaly Buka0e9439f2017-03-16 00:51:57575 return;
Vitaly Bukab2c4fb52017-03-16 18:50:40576 }
Vitaly Buka796b1122017-03-03 22:42:02577 T tmp = *value;
578 for (int i = 0; i < 10; ++i) {
579 *value = mutate(*value);
Vitaly Buka0e9439f2017-03-16 00:51:57580 if (!enforce_changes_ || *value != tmp) return;
Vitaly Buka796b1122017-03-03 22:42:02581 }
582 }
583
Vitaly Buka1c91e722020-01-26 05:56:22584 int size_increase_hint_;
Vitaly Buka0e9439f2017-03-16 00:51:57585 size_t enforce_changes_;
Vitaly Bukaaf8136f2017-06-09 23:40:12586 bool enforce_utf8_strings_;
Vitaly Bukaf62086c2020-01-29 09:11:23587 const ConstMessages& sources_;
Vitaly Bukae79e0182017-03-02 00:02:14588 Mutator* mutator_;
Vitaly Buka432b5452016-12-09 22:42:09589};
590
Vitaly Buka5d013202017-02-25 00:50:11591namespace {
592
Vitaly Bukad4ab1e72017-03-04 07:51:19593struct MutateField : public FieldFunction<MutateField> {
Vitaly Buka5d013202017-02-25 00:50:11594 template <class T>
Vitaly Buka1c91e722020-01-26 05:56:22595 void ForType(const FieldInstance& field, int size_increase_hint,
Vitaly Bukaf62086c2020-01-29 09:11:23596 const ConstMessages& sources, Mutator* mutator) const {
Vitaly Buka5d013202017-02-25 00:50:11597 T value;
598 field.Load(&value);
Vitaly Bukaf62086c2020-01-29 09:11:23599 FieldMutator(size_increase_hint, true, field.EnforceUtf8(), sources,
600 mutator)
Vitaly Bukaaf8136f2017-06-09 23:40:12601 .Mutate(&value);
Vitaly Buka5d013202017-02-25 00:50:11602 field.Store(value);
603 }
Vitaly Buka5d013202017-02-25 00:50:11604};
605
Vitaly Bukad4ab1e72017-03-04 07:51:19606struct CreateField : public FieldFunction<CreateField> {
Vitaly Buka5d013202017-02-25 00:50:11607 public:
Vitaly Buka5d013202017-02-25 00:50:11608 template <class T>
Vitaly Buka1c91e722020-01-26 05:56:22609 void ForType(const FieldInstance& field, int size_increase_hint,
Vitaly Bukaf62086c2020-01-29 09:11:23610 const ConstMessages& sources, Mutator* mutator) const {
Vitaly Buka5d013202017-02-25 00:50:11611 T value;
612 field.GetDefault(&value);
Vitaly Buka0e9439f2017-03-16 00:51:57613 FieldMutator field_mutator(size_increase_hint,
Vitaly Bukaaf8136f2017-06-09 23:40:12614 false /* defaults could be useful */,
Vitaly Bukaf62086c2020-01-29 09:11:23615 field.EnforceUtf8(), sources, mutator);
Vitaly Buka0e9439f2017-03-16 00:51:57616 field_mutator.Mutate(&value);
Vitaly Buka5d013202017-02-25 00:50:11617 field.Create(value);
618 }
Vitaly Buka5d013202017-02-25 00:50:11619};
620
621} // namespace
622
Vitaly Buka379f5ab2019-08-31 23:11:59623void Mutator::Seed(uint32_t value) { random_.seed(value); }
Vitaly Buka432b5452016-12-09 22:42:09624
Vitaly Bukabaa13292020-01-26 03:39:28625void Mutator::Mutate(Message* message, size_t max_size_hint) {
Vitaly Bukadbc4c0f2020-01-29 09:22:21626 UnpackedAny any;
627 UnpackAny(*message, &any);
628
Vitaly Bukaf62086c2020-01-29 09:11:23629 Messages messages;
Vitaly Bukadbc4c0f2020-01-29 09:22:21630 messages.reserve(any.size() + 1);
Vitaly Bukaf62086c2020-01-29 09:11:23631 messages.push_back(message);
Vitaly Bukadbc4c0f2020-01-29 09:22:21632 for (const auto& kv : any) messages.push_back(kv.second.get());
633
Vitaly Bukaf62086c2020-01-29 09:11:23634 ConstMessages sources(messages.begin(), messages.end());
635 MutateImpl(sources, messages, false,
Vitaly Buka1c91e722020-01-26 05:56:22636 static_cast<int>(max_size_hint) -
637 static_cast<int>(message->ByteSizeLong()));
Vitaly Buka0e17fd72016-11-18 18:02:46638
Vitaly Bukadbc4c0f2020-01-29 09:22:21639 PostProcessing(keep_initialized_, post_processors_, any, &random_)
Vitaly Buka045acda2020-01-29 08:26:35640 .Run(message, kMaxInitializeDepth);
Vitaly Buka9eaf0632020-01-16 01:30:20641 assert(IsInitialized(*message));
Peter Foleyfe76ed62019-10-01 00:03:37642}
643
Vitaly Buka4b3d7832020-01-29 08:34:12644void Mutator::CrossOver(const Message& message1, Message* message2,
645 size_t max_size_hint) {
Vitaly Bukadbc4c0f2020-01-29 09:22:21646 UnpackedAny any;
647 UnpackAny(*message2, &any);
648
Vitaly Bukaf62086c2020-01-29 09:11:23649 Messages messages;
Vitaly Bukadbc4c0f2020-01-29 09:22:21650 messages.reserve(any.size() + 1);
Vitaly Bukaf62086c2020-01-29 09:11:23651 messages.push_back(message2);
Vitaly Bukadbc4c0f2020-01-29 09:22:21652 for (auto& kv : any) messages.push_back(kv.second.get());
653
654 UnpackAny(message1, &any);
655
Vitaly Bukaf62086c2020-01-29 09:11:23656 ConstMessages sources;
Vitaly Bukadbc4c0f2020-01-29 09:22:21657 sources.reserve(any.size() + 2);
Vitaly Bukaf62086c2020-01-29 09:11:23658 sources.push_back(&message1);
Vitaly Buka1989ccb2020-02-04 23:40:30659 sources.push_back(message2);
Vitaly Bukadbc4c0f2020-01-29 09:22:21660 for (const auto& kv : any) sources.push_back(kv.second.get());
Vitaly Buka4b3d7832020-01-29 08:34:12661
Vitaly Bukadbc4c0f2020-01-29 09:22:21662 MutateImpl(sources, messages, true,
663 static_cast<int>(max_size_hint) -
664 static_cast<int>(message2->ByteSizeLong()));
665
666 PostProcessing(keep_initialized_, post_processors_, any, &random_)
Vitaly Buka4b3d7832020-01-29 08:34:12667 .Run(message2, kMaxInitializeDepth);
668 assert(IsInitialized(*message2));
669}
670
Vitaly Bukad3600272020-01-27 07:24:10671void Mutator::RegisterPostProcessor(const Descriptor* desc,
Peter Foleyfe76ed62019-10-01 00:03:37672 PostProcess callback) {
673 post_processors_.emplace(desc, callback);
674}
675
Vitaly Bukaf62086c2020-01-29 09:11:23676bool Mutator::MutateImpl(const ConstMessages& sources, const Messages& messages,
Vitaly Buka9f357ae2020-01-27 07:17:11677 bool copy_clone_only, int size_increase_hint) {
Vitaly Buka1c91e722020-01-26 05:56:22678 if (size_increase_hint > 0) size_increase_hint /= 2;
Vitaly Bukac1839912020-01-27 06:32:57679 MutationBitset mutations;
Vitaly Buka9f357ae2020-01-27 07:17:11680 if (copy_clone_only) {
681 mutations[static_cast<size_t>(Mutation::Copy)] = true;
682 mutations[static_cast<size_t>(Mutation::Clone)] = true;
683 } else if (size_increase_hint <= 16) {
Vitaly Bukac1839912020-01-27 06:32:57684 mutations[static_cast<size_t>(Mutation::Delete)] = true;
685 } else {
686 mutations.set();
687 }
Vitaly Buka9f357ae2020-01-27 07:17:11688 while (mutations.any()) {
Vitaly Bukaf62086c2020-01-29 09:11:23689 MutationSampler mutation(keep_initialized_, mutations, &random_);
690 for (Message* message : messages) mutation.Sample(message);
691
Vitaly Buka3183b0d2019-09-06 22:11:10692 switch (mutation.mutation()) {
693 case Mutation::None:
Vitaly Buka9f357ae2020-01-27 07:17:11694 return true;
Vitaly Buka3183b0d2019-09-06 22:11:10695 case Mutation::Add:
Vitaly Bukaf62086c2020-01-29 09:11:23696 CreateField()(mutation.field(), size_increase_hint, sources, this);
Vitaly Buka9f357ae2020-01-27 07:17:11697 return true;
Vitaly Buka3183b0d2019-09-06 22:11:10698 case Mutation::Mutate:
Vitaly Bukaf62086c2020-01-29 09:11:23699 MutateField()(mutation.field(), size_increase_hint, sources, this);
Vitaly Buka9f357ae2020-01-27 07:17:11700 return true;
Vitaly Buka3183b0d2019-09-06 22:11:10701 case Mutation::Delete:
702 DeleteField()(mutation.field());
Vitaly Buka9f357ae2020-01-27 07:17:11703 return true;
Vitaly Buka5635a7a2020-01-26 09:52:40704 case Mutation::Clone: {
Vitaly Buka9f357ae2020-01-27 07:17:11705 CreateDefaultField()(mutation.field());
Vitaly Buka5635a7a2020-01-26 09:52:40706 DataSourceSampler source_sampler(mutation.field(), &random_,
Vitaly Bukaf62086c2020-01-29 09:11:23707 size_increase_hint);
708 for (const Message* source : sources) source_sampler.Sample(*source);
Vitaly Buka1989ccb2020-02-04 23:40:30709 if (source_sampler.IsEmpty()) {
710 if (!IsProto3SimpleField(*mutation.field().descriptor()))
711 return true; // CreateField is enough for proto2.
712 break;
713 }
Vitaly Buka5635a7a2020-01-26 09:52:40714 CopyField()(source_sampler.field(), mutation.field());
Vitaly Buka9f357ae2020-01-27 07:17:11715 return true;
Vitaly Buka5635a7a2020-01-26 09:52:40716 }
Vitaly Buka3183b0d2019-09-06 22:11:10717 case Mutation::Copy: {
Vitaly Buka5cd166e2020-01-26 06:33:05718 DataSourceSampler source_sampler(mutation.field(), &random_,
Vitaly Bukaf62086c2020-01-29 09:11:23719 size_increase_hint);
720 for (const Message* source : sources) source_sampler.Sample(*source);
Vitaly Buka0f63f912020-01-24 23:02:45721 if (source_sampler.IsEmpty()) break;
722 CopyField()(source_sampler.field(), mutation.field());
Vitaly Buka9f357ae2020-01-27 07:17:11723 return true;
Vitaly Buka3183b0d2019-09-06 22:11:10724 }
725 default:
726 assert(false && "unexpected mutation");
Vitaly Buka9f357ae2020-01-27 07:17:11727 return false;
Vitaly Buka3183b0d2019-09-06 22:11:10728 }
Vitaly Buka1989ccb2020-02-04 23:40:30729
730 // Don't try same mutation next time.
731 mutations[static_cast<size_t>(mutation.mutation())] = false;
Vitaly Buka3183b0d2019-09-06 22:11:10732 }
Vitaly Buka9f357ae2020-01-27 07:17:11733 return false;
Vitaly Buka3183b0d2019-09-06 22:11:10734}
735
Vitaly Buka379f5ab2019-08-31 23:11:59736int32_t Mutator::MutateInt32(int32_t value) { return FlipBit(value, &random_); }
Vitaly Bukae79e0182017-03-02 00:02:14737
Vitaly Buka379f5ab2019-08-31 23:11:59738int64_t Mutator::MutateInt64(int64_t value) { return FlipBit(value, &random_); }
Vitaly Bukae79e0182017-03-02 00:02:14739
740uint32_t Mutator::MutateUInt32(uint32_t value) {
Vitaly Buka379f5ab2019-08-31 23:11:59741 return FlipBit(value, &random_);
Vitaly Buka4af611d2016-12-04 02:57:32742}
743
Vitaly Bukae79e0182017-03-02 00:02:14744uint64_t Mutator::MutateUInt64(uint64_t value) {
Vitaly Buka379f5ab2019-08-31 23:11:59745 return FlipBit(value, &random_);
Vitaly Buka4af611d2016-12-04 02:57:32746}
747
Vitaly Buka379f5ab2019-08-31 23:11:59748float Mutator::MutateFloat(float value) { return FlipBit(value, &random_); }
Vitaly Buka4af611d2016-12-04 02:57:32749
Vitaly Buka379f5ab2019-08-31 23:11:59750double Mutator::MutateDouble(double value) { return FlipBit(value, &random_); }
Vitaly Buka4af611d2016-12-04 02:57:32751
Vitaly Bukae79e0182017-03-02 00:02:14752bool Mutator::MutateBool(bool value) { return !value; }
Vitaly Buka4af611d2016-12-04 02:57:32753
Vitaly Bukae79e0182017-03-02 00:02:14754size_t Mutator::MutateEnum(size_t index, size_t item_count) {
Vitaly Bukaee1c76a2017-03-15 17:48:53755 if (item_count <= 1) return 0;
Vitaly Buka379f5ab2019-08-31 23:11:59756 return (index + 1 + GetRandomIndex(&random_, item_count - 1)) % item_count;
Vitaly Buka4af611d2016-12-04 02:57:32757}
758
Vitaly Bukae79e0182017-03-02 00:02:14759std::string Mutator::MutateString(const std::string& value,
Vitaly Buka1c91e722020-01-26 05:56:22760 int size_increase_hint) {
Vitaly Buka4af611d2016-12-04 02:57:32761 std::string result = value;
Vitaly Buka5d013202017-02-25 00:50:11762
Vitaly Buka379f5ab2019-08-31 23:11:59763 while (!result.empty() && GetRandomBool(&random_)) {
764 result.erase(GetRandomIndex(&random_, result.size()), 1);
Vitaly Buka432b5452016-12-09 22:42:09765 }
766
Vitaly Buka1c91e722020-01-26 05:56:22767 while (size_increase_hint > 0 &&
768 result.size() < static_cast<size_t>(size_increase_hint) &&
769 GetRandomBool(&random_)) {
Vitaly Buka379f5ab2019-08-31 23:11:59770 size_t index = GetRandomIndex(&random_, result.size() + 1);
771 result.insert(result.begin() + index, GetRandomIndex(&random_, 1 << 8));
Vitaly Buka432b5452016-12-09 22:42:09772 }
773
Vitaly Bukac020de12017-03-04 03:36:23774 if (result != value) return result;
775
776 if (result.empty()) {
Vitaly Buka379f5ab2019-08-31 23:11:59777 result.push_back(GetRandomIndex(&random_, 1 << 8));
Vitaly Bukac020de12017-03-04 03:36:23778 return result;
779 }
780
Vitaly Buka4af611d2016-12-04 02:57:32781 if (!result.empty())
Vitaly Buka379f5ab2019-08-31 23:11:59782 FlipBit(result.size(), reinterpret_cast<uint8_t*>(&result[0]), &random_);
Vitaly Buka4af611d2016-12-04 02:57:32783 return result;
784}
Vitaly Buka432b5452016-12-09 22:42:09785
Vitaly Bukaaf8136f2017-06-09 23:40:12786std::string Mutator::MutateUtf8String(const std::string& value,
Vitaly Buka1c91e722020-01-26 05:56:22787 int size_increase_hint) {
Vitaly Bukaaf8136f2017-06-09 23:40:12788 std::string str = MutateString(value, size_increase_hint);
Vitaly Buka379f5ab2019-08-31 23:11:59789 FixUtf8String(&str, &random_);
Vitaly Bukaaf8136f2017-06-09 23:40:12790 return str;
791}
792
Vitaly Buka9eaf0632020-01-16 01:30:20793bool Mutator::IsInitialized(const Message& message) const {
794 if (!keep_initialized_ || message.IsInitialized()) return true;
795 std::cerr << "Uninitialized: " << message.DebugString() << "\n";
796 return false;
797}
798
Vitaly Buka432b5452016-12-09 22:42:09799} // namespace protobuf_mutator