1 //===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 // Mutate a test input.
9 //===----------------------------------------------------------------------===//
11 #include "FuzzerDefs.h"
12 #include "FuzzerExtFunctions.h"
14 #include "FuzzerMutate.h"
15 #include "FuzzerOptions.h"
16 #include "FuzzerTracePC.h"
20 const size_t Dictionary::kMaxDictSize
;
21 static const size_t kMaxMutationsToPrint
= 10;
23 static void PrintASCII(const Word
&W
, const char *PrintAfter
) {
24 PrintASCII(W
.data(), W
.size(), PrintAfter
);
27 MutationDispatcher::MutationDispatcher(Random
&Rand
,
28 const FuzzingOptions
&Options
)
29 : Rand(Rand
), Options(Options
) {
30 DefaultMutators
.insert(
31 DefaultMutators
.begin(),
33 {&MutationDispatcher::Mutate_EraseBytes
, "EraseBytes"},
34 {&MutationDispatcher::Mutate_InsertByte
, "InsertByte"},
35 {&MutationDispatcher::Mutate_InsertRepeatedBytes
,
36 "InsertRepeatedBytes"},
37 {&MutationDispatcher::Mutate_ChangeByte
, "ChangeByte"},
38 {&MutationDispatcher::Mutate_ChangeBit
, "ChangeBit"},
39 {&MutationDispatcher::Mutate_ShuffleBytes
, "ShuffleBytes"},
40 {&MutationDispatcher::Mutate_ChangeASCIIInteger
, "ChangeASCIIInt"},
41 {&MutationDispatcher::Mutate_ChangeBinaryInteger
, "ChangeBinInt"},
42 {&MutationDispatcher::Mutate_CopyPart
, "CopyPart"},
43 {&MutationDispatcher::Mutate_CrossOver
, "CrossOver"},
44 {&MutationDispatcher::Mutate_AddWordFromManualDictionary
,
46 {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary
,
50 DefaultMutators
.push_back(
51 {&MutationDispatcher::Mutate_AddWordFromTORC
, "CMP"});
53 if (EF
->LLVMFuzzerCustomMutator
)
54 Mutators
.push_back({&MutationDispatcher::Mutate_Custom
, "Custom"});
56 Mutators
= DefaultMutators
;
58 if (EF
->LLVMFuzzerCustomCrossOver
)
60 {&MutationDispatcher::Mutate_CustomCrossOver
, "CustomCrossOver"});
63 static char RandCh(Random
&Rand
) {
65 return static_cast<char>(Rand(256));
66 const char Special
[] = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00";
67 return Special
[Rand(sizeof(Special
) - 1)];
70 size_t MutationDispatcher::Mutate_Custom(uint8_t *Data
, size_t Size
,
72 if (EF
->__msan_unpoison
)
73 EF
->__msan_unpoison(Data
, Size
);
74 if (EF
->__msan_unpoison_param
)
75 EF
->__msan_unpoison_param(4);
76 return EF
->LLVMFuzzerCustomMutator(Data
, Size
, MaxSize
,
77 Rand
.Rand
<unsigned int>());
80 size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data
, size_t Size
,
84 if (!CrossOverWith
) return 0;
85 const Unit
&Other
= *CrossOverWith
;
88 CustomCrossOverInPlaceHere
.resize(MaxSize
);
89 auto &U
= CustomCrossOverInPlaceHere
;
91 if (EF
->__msan_unpoison
) {
92 EF
->__msan_unpoison(Data
, Size
);
93 EF
->__msan_unpoison(Other
.data(), Other
.size());
94 EF
->__msan_unpoison(U
.data(), U
.size());
96 if (EF
->__msan_unpoison_param
)
97 EF
->__msan_unpoison_param(7);
98 size_t NewSize
= EF
->LLVMFuzzerCustomCrossOver(
99 Data
, Size
, Other
.data(), Other
.size(), U
.data(), U
.size(),
100 Rand
.Rand
<unsigned int>());
104 assert(NewSize
<= MaxSize
&& "CustomCrossOver returned overisized unit");
105 memcpy(Data
, U
.data(), NewSize
);
109 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data
, size_t Size
,
111 if (Size
> MaxSize
|| Size
== 0) return 0;
112 size_t ShuffleAmount
=
113 Rand(std::min(Size
, (size_t)8)) + 1; // [1,8] and <= Size.
114 size_t ShuffleStart
= Rand(Size
- ShuffleAmount
);
115 assert(ShuffleStart
+ ShuffleAmount
<= Size
);
116 std::shuffle(Data
+ ShuffleStart
, Data
+ ShuffleStart
+ ShuffleAmount
, Rand
);
120 size_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data
, size_t Size
,
122 if (Size
<= 1) return 0;
123 size_t N
= Rand(Size
/ 2) + 1;
125 size_t Idx
= Rand(Size
- N
+ 1);
126 // Erase Data[Idx:Idx+N].
127 memmove(Data
+ Idx
, Data
+ Idx
+ N
, Size
- Idx
- N
);
128 // Printf("Erase: %zd %zd => %zd; Idx %zd\n", N, Size, Size - N, Idx);
132 size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data
, size_t Size
,
134 if (Size
>= MaxSize
) return 0;
135 size_t Idx
= Rand(Size
+ 1);
136 // Insert new value at Data[Idx].
137 memmove(Data
+ Idx
+ 1, Data
+ Idx
, Size
- Idx
);
138 Data
[Idx
] = RandCh(Rand
);
142 size_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data
,
145 const size_t kMinBytesToInsert
= 3;
146 if (Size
+ kMinBytesToInsert
>= MaxSize
) return 0;
147 size_t MaxBytesToInsert
= std::min(MaxSize
- Size
, (size_t)128);
148 size_t N
= Rand(MaxBytesToInsert
- kMinBytesToInsert
+ 1) + kMinBytesToInsert
;
149 assert(Size
+ N
<= MaxSize
&& N
);
150 size_t Idx
= Rand(Size
+ 1);
151 // Insert new values at Data[Idx].
152 memmove(Data
+ Idx
+ N
, Data
+ Idx
, Size
- Idx
);
153 // Give preference to 0x00 and 0xff.
154 uint8_t Byte
= static_cast<uint8_t>(
155 Rand
.RandBool() ? Rand(256) : (Rand
.RandBool() ? 0 : 255));
156 for (size_t i
= 0; i
< N
; i
++)
157 Data
[Idx
+ i
] = Byte
;
161 size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data
, size_t Size
,
163 if (Size
> MaxSize
) return 0;
164 size_t Idx
= Rand(Size
);
165 Data
[Idx
] = RandCh(Rand
);
169 size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data
, size_t Size
,
171 if (Size
> MaxSize
) return 0;
172 size_t Idx
= Rand(Size
);
173 Data
[Idx
] ^= 1 << Rand(8);
177 size_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data
,
180 return AddWordFromDictionary(ManualDictionary
, Data
, Size
, MaxSize
);
183 size_t MutationDispatcher::ApplyDictionaryEntry(uint8_t *Data
, size_t Size
,
185 DictionaryEntry
&DE
) {
186 const Word
&W
= DE
.GetW();
187 bool UsePositionHint
= DE
.HasPositionHint() &&
188 DE
.GetPositionHint() + W
.size() < Size
&&
190 if (Rand
.RandBool()) { // Insert W.
191 if (Size
+ W
.size() > MaxSize
) return 0;
192 size_t Idx
= UsePositionHint
? DE
.GetPositionHint() : Rand(Size
+ 1);
193 memmove(Data
+ Idx
+ W
.size(), Data
+ Idx
, Size
- Idx
);
194 memcpy(Data
+ Idx
, W
.data(), W
.size());
196 } else { // Overwrite some bytes with W.
197 if (W
.size() > Size
) return 0;
199 UsePositionHint
? DE
.GetPositionHint() : Rand(Size
+ 1 - W
.size());
200 memcpy(Data
+ Idx
, W
.data(), W
.size());
205 // Somewhere in the past we have observed a comparison instructions
206 // with arguments Arg1 Arg2. This function tries to guess a dictionary
207 // entry that will satisfy that comparison.
208 // It first tries to find one of the arguments (possibly swapped) in the
209 // input and if it succeeds it creates a DE with a position hint.
210 // Otherwise it creates a DE with one of the arguments w/o a position hint.
211 DictionaryEntry
MutationDispatcher::MakeDictionaryEntryFromCMP(
212 const void *Arg1
, const void *Arg2
,
213 const void *Arg1Mutation
, const void *Arg2Mutation
,
214 size_t ArgSize
, const uint8_t *Data
,
216 bool HandleFirst
= Rand
.RandBool();
217 const void *ExistingBytes
, *DesiredBytes
;
219 const uint8_t *End
= Data
+ Size
;
220 for (int Arg
= 0; Arg
< 2; Arg
++) {
221 ExistingBytes
= HandleFirst
? Arg1
: Arg2
;
222 DesiredBytes
= HandleFirst
? Arg2Mutation
: Arg1Mutation
;
223 HandleFirst
= !HandleFirst
;
224 W
.Set(reinterpret_cast<const uint8_t*>(DesiredBytes
), ArgSize
);
225 const size_t kMaxNumPositions
= 8;
226 size_t Positions
[kMaxNumPositions
];
227 size_t NumPositions
= 0;
228 for (const uint8_t *Cur
= Data
;
229 Cur
< End
&& NumPositions
< kMaxNumPositions
; Cur
++) {
231 (const uint8_t *)SearchMemory(Cur
, End
- Cur
, ExistingBytes
, ArgSize
);
233 Positions
[NumPositions
++] = Cur
- Data
;
235 if (!NumPositions
) continue;
236 return DictionaryEntry(W
, Positions
[Rand(NumPositions
)]);
238 DictionaryEntry
DE(W
);
244 DictionaryEntry
MutationDispatcher::MakeDictionaryEntryFromCMP(
245 T Arg1
, T Arg2
, const uint8_t *Data
, size_t Size
) {
246 if (Rand
.RandBool()) Arg1
= Bswap(Arg1
);
247 if (Rand
.RandBool()) Arg2
= Bswap(Arg2
);
248 T Arg1Mutation
= static_cast<T
>(Arg1
+ Rand(-1, 1));
249 T Arg2Mutation
= static_cast<T
>(Arg2
+ Rand(-1, 1));
250 return MakeDictionaryEntryFromCMP(&Arg1
, &Arg2
, &Arg1Mutation
, &Arg2Mutation
,
251 sizeof(Arg1
), Data
, Size
);
254 DictionaryEntry
MutationDispatcher::MakeDictionaryEntryFromCMP(
255 const Word
&Arg1
, const Word
&Arg2
, const uint8_t *Data
, size_t Size
) {
256 return MakeDictionaryEntryFromCMP(Arg1
.data(), Arg2
.data(), Arg1
.data(),
257 Arg2
.data(), Arg1
.size(), Data
, Size
);
260 size_t MutationDispatcher::Mutate_AddWordFromTORC(
261 uint8_t *Data
, size_t Size
, size_t MaxSize
) {
266 auto X
= TPC
.TORC8
.Get(Rand
.Rand
<size_t>());
267 DE
= MakeDictionaryEntryFromCMP(X
.A
, X
.B
, Data
, Size
);
270 auto X
= TPC
.TORC4
.Get(Rand
.Rand
<size_t>());
271 if ((X
.A
>> 16) == 0 && (X
.B
>> 16) == 0 && Rand
.RandBool())
272 DE
= MakeDictionaryEntryFromCMP((uint16_t)X
.A
, (uint16_t)X
.B
, Data
, Size
);
274 DE
= MakeDictionaryEntryFromCMP(X
.A
, X
.B
, Data
, Size
);
277 auto X
= TPC
.TORCW
.Get(Rand
.Rand
<size_t>());
278 DE
= MakeDictionaryEntryFromCMP(X
.A
, X
.B
, Data
, Size
);
280 case 3: if (Options
.UseMemmem
) {
281 auto X
= TPC
.MMT
.Get(Rand
.Rand
<size_t>());
282 DE
= DictionaryEntry(X
);
287 if (!DE
.GetW().size()) return 0;
288 Size
= ApplyDictionaryEntry(Data
, Size
, MaxSize
, DE
);
290 DictionaryEntry
&DERef
=
291 CmpDictionaryEntriesDeque
[CmpDictionaryEntriesDequeIdx
++ %
292 kCmpDictionaryEntriesDequeSize
];
294 CurrentDictionaryEntrySequence
.push_back(&DERef
);
298 size_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(
299 uint8_t *Data
, size_t Size
, size_t MaxSize
) {
300 return AddWordFromDictionary(PersistentAutoDictionary
, Data
, Size
, MaxSize
);
303 size_t MutationDispatcher::AddWordFromDictionary(Dictionary
&D
, uint8_t *Data
,
304 size_t Size
, size_t MaxSize
) {
305 if (Size
> MaxSize
) return 0;
306 if (D
.empty()) return 0;
307 DictionaryEntry
&DE
= D
[Rand(D
.size())];
308 Size
= ApplyDictionaryEntry(Data
, Size
, MaxSize
, DE
);
311 CurrentDictionaryEntrySequence
.push_back(&DE
);
315 // Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
317 size_t MutationDispatcher::CopyPartOf(const uint8_t *From
, size_t FromSize
,
318 uint8_t *To
, size_t ToSize
) {
319 // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
320 size_t ToBeg
= Rand(ToSize
);
321 size_t CopySize
= Rand(ToSize
- ToBeg
) + 1;
322 assert(ToBeg
+ CopySize
<= ToSize
);
323 CopySize
= std::min(CopySize
, FromSize
);
324 size_t FromBeg
= Rand(FromSize
- CopySize
+ 1);
325 assert(FromBeg
+ CopySize
<= FromSize
);
326 memmove(To
+ ToBeg
, From
+ FromBeg
, CopySize
);
330 // Inserts part of From[0,ToSize) into To.
331 // Returns new size of To on success or 0 on failure.
332 size_t MutationDispatcher::InsertPartOf(const uint8_t *From
, size_t FromSize
,
333 uint8_t *To
, size_t ToSize
,
335 if (ToSize
>= MaxToSize
) return 0;
336 size_t AvailableSpace
= MaxToSize
- ToSize
;
337 size_t MaxCopySize
= std::min(AvailableSpace
, FromSize
);
338 size_t CopySize
= Rand(MaxCopySize
) + 1;
339 size_t FromBeg
= Rand(FromSize
- CopySize
+ 1);
340 assert(FromBeg
+ CopySize
<= FromSize
);
341 size_t ToInsertPos
= Rand(ToSize
+ 1);
342 assert(ToInsertPos
+ CopySize
<= MaxToSize
);
343 size_t TailSize
= ToSize
- ToInsertPos
;
345 MutateInPlaceHere
.resize(MaxToSize
);
346 memcpy(MutateInPlaceHere
.data(), From
+ FromBeg
, CopySize
);
347 memmove(To
+ ToInsertPos
+ CopySize
, To
+ ToInsertPos
, TailSize
);
348 memmove(To
+ ToInsertPos
, MutateInPlaceHere
.data(), CopySize
);
350 memmove(To
+ ToInsertPos
+ CopySize
, To
+ ToInsertPos
, TailSize
);
351 memmove(To
+ ToInsertPos
, From
+ FromBeg
, CopySize
);
353 return ToSize
+ CopySize
;
356 size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data
, size_t Size
,
358 if (Size
> MaxSize
|| Size
== 0) return 0;
359 // If Size == MaxSize, `InsertPartOf(...)` will
360 // fail so there's no point using it in this case.
361 if (Size
== MaxSize
|| Rand
.RandBool())
362 return CopyPartOf(Data
, Size
, Data
, Size
);
364 return InsertPartOf(Data
, Size
, Data
, Size
, MaxSize
);
367 size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data
, size_t Size
,
369 if (Size
> MaxSize
) return 0;
370 size_t B
= Rand(Size
);
371 while (B
< Size
&& !isdigit(Data
[B
])) B
++;
372 if (B
== Size
) return 0;
374 while (E
< Size
&& isdigit(Data
[E
])) E
++;
376 // now we have digits in [B, E).
377 // strtol and friends don't accept non-zero-teminated data, parse it manually.
378 uint64_t Val
= Data
[B
] - '0';
379 for (size_t i
= B
+ 1; i
< E
; i
++)
380 Val
= Val
* 10 + Data
[i
] - '0';
382 // Mutate the integer value.
384 case 0: Val
++; break;
385 case 1: Val
--; break;
386 case 2: Val
/= 2; break;
387 case 3: Val
*= 2; break;
388 case 4: Val
= Rand(Val
* Val
); break;
391 // Just replace the bytes with the new ones, don't bother moving bytes.
392 for (size_t i
= B
; i
< E
; i
++) {
393 size_t Idx
= E
+ B
- i
- 1;
394 assert(Idx
>= B
&& Idx
< E
);
395 Data
[Idx
] = (Val
% 10) + '0';
402 size_t ChangeBinaryInteger(uint8_t *Data
, size_t Size
, Random
&Rand
) {
403 if (Size
< sizeof(T
)) return 0;
404 size_t Off
= Rand(Size
- sizeof(T
) + 1);
405 assert(Off
+ sizeof(T
) <= Size
);
407 if (Off
< 64 && !Rand(4)) {
408 Val
= static_cast<T
>(Size
);
412 memcpy(&Val
, Data
+ Off
, sizeof(Val
));
413 T Add
= static_cast<T
>(Rand(21));
416 Val
= Bswap(T(Bswap(Val
) + Add
)); // Add assuming different endiannes.
418 Val
= Val
+ Add
; // Add assuming current endiannes.
419 if (Add
== 0 || Rand
.RandBool()) // Maybe negate.
422 memcpy(Data
+ Off
, &Val
, sizeof(Val
));
426 size_t MutationDispatcher::Mutate_ChangeBinaryInteger(uint8_t *Data
,
429 if (Size
> MaxSize
) return 0;
431 case 3: return ChangeBinaryInteger
<uint64_t>(Data
, Size
, Rand
);
432 case 2: return ChangeBinaryInteger
<uint32_t>(Data
, Size
, Rand
);
433 case 1: return ChangeBinaryInteger
<uint16_t>(Data
, Size
, Rand
);
434 case 0: return ChangeBinaryInteger
<uint8_t>(Data
, Size
, Rand
);
440 size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data
, size_t Size
,
442 if (Size
> MaxSize
) return 0;
443 if (Size
== 0) return 0;
444 if (!CrossOverWith
) return 0;
445 const Unit
&O
= *CrossOverWith
;
446 if (O
.empty()) return 0;
450 MutateInPlaceHere
.resize(MaxSize
);
451 NewSize
= CrossOver(Data
, Size
, O
.data(), O
.size(),
452 MutateInPlaceHere
.data(), MaxSize
);
453 memcpy(Data
, MutateInPlaceHere
.data(), NewSize
);
456 NewSize
= InsertPartOf(O
.data(), O
.size(), Data
, Size
, MaxSize
);
458 NewSize
= CopyPartOf(O
.data(), O
.size(), Data
, Size
);
461 NewSize
= CopyPartOf(O
.data(), O
.size(), Data
, Size
);
465 assert(NewSize
> 0 && "CrossOver returned empty unit");
466 assert(NewSize
<= MaxSize
&& "CrossOver returned overisized unit");
470 void MutationDispatcher::StartMutationSequence() {
471 CurrentMutatorSequence
.clear();
472 CurrentDictionaryEntrySequence
.clear();
475 // Copy successful dictionary entries to PersistentAutoDictionary.
476 void MutationDispatcher::RecordSuccessfulMutationSequence() {
477 for (auto DE
: CurrentDictionaryEntrySequence
) {
478 // PersistentAutoDictionary.AddWithSuccessCountOne(DE);
479 DE
->IncSuccessCount();
480 assert(DE
->GetW().size());
481 // Linear search is fine here as this happens seldom.
482 if (!PersistentAutoDictionary
.ContainsWord(DE
->GetW()))
483 PersistentAutoDictionary
.push_back(*DE
);
487 void MutationDispatcher::PrintRecommendedDictionary() {
488 std::vector
<DictionaryEntry
> V
;
489 for (auto &DE
: PersistentAutoDictionary
)
490 if (!ManualDictionary
.ContainsWord(DE
.GetW()))
492 if (V
.empty()) return;
493 Printf("###### Recommended dictionary. ######\n");
495 assert(DE
.GetW().size());
497 PrintASCII(DE
.GetW(), "\"");
498 Printf(" # Uses: %zd\n", DE
.GetUseCount());
500 Printf("###### End of recommended dictionary. ######\n");
503 void MutationDispatcher::PrintMutationSequence(bool Verbose
) {
504 Printf("MS: %zd ", CurrentMutatorSequence
.size());
505 size_t EntriesToPrint
=
506 Verbose
? CurrentMutatorSequence
.size()
507 : std::min(kMaxMutationsToPrint
, CurrentMutatorSequence
.size());
508 for (size_t i
= 0; i
< EntriesToPrint
; i
++)
509 Printf("%s-", CurrentMutatorSequence
[i
].Name
);
510 if (!CurrentDictionaryEntrySequence
.empty()) {
512 EntriesToPrint
= Verbose
? CurrentDictionaryEntrySequence
.size()
513 : std::min(kMaxMutationsToPrint
,
514 CurrentDictionaryEntrySequence
.size());
515 for (size_t i
= 0; i
< EntriesToPrint
; i
++) {
517 PrintASCII(CurrentDictionaryEntrySequence
[i
]->GetW(), "\"-");
522 std::string
MutationDispatcher::MutationSequence() {
524 for (const auto &M
: CurrentMutatorSequence
) {
531 size_t MutationDispatcher::Mutate(uint8_t *Data
, size_t Size
, size_t MaxSize
) {
532 return MutateImpl(Data
, Size
, MaxSize
, Mutators
);
535 size_t MutationDispatcher::DefaultMutate(uint8_t *Data
, size_t Size
,
537 return MutateImpl(Data
, Size
, MaxSize
, DefaultMutators
);
540 // Mutates Data in place, returns new size.
541 size_t MutationDispatcher::MutateImpl(uint8_t *Data
, size_t Size
,
543 std::vector
<Mutator
> &Mutators
) {
545 // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
546 // in which case they will return 0.
547 // Try several times before returning un-mutated data.
548 for (int Iter
= 0; Iter
< 100; Iter
++) {
549 auto M
= Mutators
[Rand(Mutators
.size())];
550 size_t NewSize
= (this->*(M
.Fn
))(Data
, Size
, MaxSize
);
551 if (NewSize
&& NewSize
<= MaxSize
) {
552 if (Options
.OnlyASCII
)
553 ToASCII(Data
, NewSize
);
554 CurrentMutatorSequence
.push_back(M
);
559 return 1; // Fallback, should not happen frequently.
562 // Mask represents the set of Data bytes that are worth mutating.
563 size_t MutationDispatcher::MutateWithMask(uint8_t *Data
, size_t Size
,
565 const std::vector
<uint8_t> &Mask
) {
566 size_t MaskedSize
= std::min(Size
, Mask
.size());
567 // * Copy the worthy bytes into a temporary array T
570 // This is totally unoptimized.
571 auto &T
= MutateWithMaskTemp
;
575 for (size_t I
= 0; I
< MaskedSize
; I
++)
577 T
[OneBits
++] = Data
[I
];
579 if (!OneBits
) return 0;
581 size_t NewSize
= Mutate(T
.data(), OneBits
, OneBits
);
582 assert(NewSize
<= OneBits
);
584 // Even if NewSize < OneBits we still use all OneBits bytes.
585 for (size_t I
= 0, J
= 0; I
< MaskedSize
; I
++)
591 void MutationDispatcher::AddWordToManualDictionary(const Word
&W
) {
592 ManualDictionary
.push_back(
593 {W
, std::numeric_limits
<size_t>::max()});
596 } // namespace fuzzer