@@ -32,6 +32,7 @@ MutationDispatcher::MutationDispatcher(Random &Rand,
32
32
{&MutationDispatcher::Mutate_ChangeBit, " ChangeBit" },
33
33
{&MutationDispatcher::Mutate_ShuffleBytes, " ShuffleBytes" },
34
34
{&MutationDispatcher::Mutate_ChangeASCIIInteger, " ChangeASCIIInt" },
35
+ {&MutationDispatcher::Mutate_CopyPart, " CopyPart" },
35
36
{&MutationDispatcher::Mutate_CrossOver, " CrossOver" },
36
37
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
37
38
" AddFromManualDict" },
@@ -51,21 +52,9 @@ MutationDispatcher::MutationDispatcher(Random &Rand,
51
52
{&MutationDispatcher::Mutate_CustomCrossOver, " CustomCrossOver" });
52
53
}
53
54
54
- static char FlipRandomBit (char X, Random &Rand) {
55
- int Bit = Rand (8 );
56
- char Mask = 1 << Bit;
57
- char R;
58
- if (X & (1 << Bit))
59
- R = X & ~Mask;
60
- else
61
- R = X | Mask;
62
- assert (R != X);
63
- return R;
64
- }
65
-
66
55
static char RandCh (Random &Rand) {
67
56
if (Rand.RandBool ()) return Rand (256 );
68
- const char *Special = " !*'();:@&=+$,/?%#[]123ABCxyz -`~." ;
57
+ const char *Special = " !*'();:@&=+$,/?%#[]012Az -`~.\xff\x00 " ;
69
58
return Special[Rand (sizeof (Special) - 1 )];
70
59
}
71
60
@@ -155,7 +144,7 @@ size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
155
144
size_t MutationDispatcher::Mutate_ChangeBit (uint8_t *Data, size_t Size ,
156
145
size_t MaxSize) {
157
146
size_t Idx = Rand (Size );
158
- Data[Idx] = FlipRandomBit (Data[Idx], Rand);
147
+ Data[Idx] ^= 1 << Rand ( 8 );
159
148
return Size ;
160
149
}
161
150
@@ -198,6 +187,55 @@ size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
198
187
return Size ;
199
188
}
200
189
190
+ // Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
191
+ // Returns ToSize.
192
+ size_t MutationDispatcher::CopyPartOf (const uint8_t *From, size_t FromSize,
193
+ uint8_t *To, size_t ToSize) {
194
+ // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
195
+ size_t ToBeg = Rand (ToSize);
196
+ size_t CopySize = Rand (ToSize - ToBeg) + 1 ;
197
+ assert (ToBeg + CopySize <= ToSize);
198
+ CopySize = std::min (CopySize, FromSize);
199
+ size_t FromBeg = Rand (FromSize - CopySize + 1 );
200
+ assert (FromBeg + CopySize <= FromSize);
201
+ memmove (To + ToBeg, From + FromBeg, CopySize);
202
+ return ToSize;
203
+ }
204
+
205
+ // Inserts part of From[0,ToSize) into To.
206
+ // Returns new size of To on success or 0 on failure.
207
+ size_t MutationDispatcher::InsertPartOf (const uint8_t *From, size_t FromSize,
208
+ uint8_t *To, size_t ToSize,
209
+ size_t MaxToSize) {
210
+ if (ToSize >= MaxToSize) return 0 ;
211
+ size_t AvailableSpace = MaxToSize - ToSize;
212
+ size_t MaxCopySize = std::min (AvailableSpace, FromSize);
213
+ size_t CopySize = Rand (MaxCopySize) + 1 ;
214
+ size_t FromBeg = Rand (FromSize - CopySize + 1 );
215
+ assert (FromBeg + CopySize <= FromSize);
216
+ size_t ToInsertPos = Rand (ToSize + 1 );
217
+ assert (ToInsertPos + CopySize <= MaxToSize);
218
+ size_t TailSize = ToSize - ToInsertPos;
219
+ if (To == From) {
220
+ MutateInPlaceHere.resize (MaxToSize);
221
+ memcpy (MutateInPlaceHere.data (), From + FromBeg, CopySize);
222
+ memmove (To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
223
+ memmove (To + ToInsertPos, MutateInPlaceHere.data (), CopySize);
224
+ } else {
225
+ memmove (To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
226
+ memmove (To + ToInsertPos, From + FromBeg, CopySize);
227
+ }
228
+ return ToSize + CopySize;
229
+ }
230
+
231
+ size_t MutationDispatcher::Mutate_CopyPart (uint8_t *Data, size_t Size ,
232
+ size_t MaxSize) {
233
+ if (Rand.RandBool ())
234
+ return CopyPartOf (Data, Size , Data, Size );
235
+ else
236
+ return InsertPartOf (Data, Size , Data, Size , MaxSize);
237
+ }
238
+
201
239
size_t MutationDispatcher::Mutate_ChangeASCIIInteger (uint8_t *Data, size_t Size ,
202
240
size_t MaxSize) {
203
241
size_t B = Rand (Size );
@@ -235,12 +273,25 @@ size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
235
273
size_t MaxSize) {
236
274
if (!Corpus || Corpus->size () < 2 || Size == 0 ) return 0 ;
237
275
size_t Idx = Rand (Corpus->size ());
238
- const Unit &Other = (*Corpus)[Idx];
239
- if (Other .empty ()) return 0 ;
276
+ const Unit &O = (*Corpus)[Idx];
277
+ if (O .empty ()) return 0 ;
240
278
MutateInPlaceHere.resize (MaxSize);
241
279
auto &U = MutateInPlaceHere;
242
- size_t NewSize =
243
- CrossOver (Data, Size , Other.data (), Other.size (), U.data (), U.size ());
280
+ size_t NewSize;
281
+ switch (Rand (3 )) {
282
+ case 0 :
283
+ NewSize = CrossOver (Data, Size , O.data (), O.size (), U.data (), U.size ());
284
+ break ;
285
+ case 1 :
286
+ NewSize = InsertPartOf (O.data (), O.size (), U.data (), U.size (), MaxSize);
287
+ if (NewSize)
288
+ break ;
289
+ // Fallthrough
290
+ case 2 :
291
+ NewSize = CopyPartOf (O.data (), O.size (), U.data (), U.size ());
292
+ break ;
293
+ default : assert (0 );
294
+ }
244
295
assert (NewSize > 0 && " CrossOver returned empty unit" );
245
296
assert (NewSize <= MaxSize && " CrossOver returned overisized unit" );
246
297
memcpy (Data, U.data (), NewSize);
0 commit comments