1 1.1 kamil //===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // Cross over test inputs. 10 1.1 kamil //===----------------------------------------------------------------------===// 11 1.1 kamil 12 1.1 kamil #include "FuzzerDefs.h" 13 1.1 kamil #include "FuzzerMutate.h" 14 1.1 kamil #include "FuzzerRandom.h" 15 1.1 kamil #include <cstring> 16 1.1 kamil 17 1.1 kamil namespace fuzzer { 18 1.1 kamil 19 1.1 kamil // Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out. 20 1.1 kamil size_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1, 21 1.1 kamil const uint8_t *Data2, size_t Size2, 22 1.1 kamil uint8_t *Out, size_t MaxOutSize) { 23 1.1 kamil assert(Size1 || Size2); 24 1.1 kamil MaxOutSize = Rand(MaxOutSize) + 1; 25 1.1 kamil size_t OutPos = 0; 26 1.1 kamil size_t Pos1 = 0; 27 1.1 kamil size_t Pos2 = 0; 28 1.1 kamil size_t *InPos = &Pos1; 29 1.1 kamil size_t InSize = Size1; 30 1.1 kamil const uint8_t *Data = Data1; 31 1.1 kamil bool CurrentlyUsingFirstData = true; 32 1.1 kamil while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) { 33 1.1 kamil // Merge a part of Data into Out. 34 1.1 kamil size_t OutSizeLeft = MaxOutSize - OutPos; 35 1.1 kamil if (*InPos < InSize) { 36 1.1 kamil size_t InSizeLeft = InSize - *InPos; 37 1.1 kamil size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft); 38 1.1 kamil size_t ExtraSize = Rand(MaxExtraSize) + 1; 39 1.1 kamil memcpy(Out + OutPos, Data + *InPos, ExtraSize); 40 1.1 kamil OutPos += ExtraSize; 41 1.1 kamil (*InPos) += ExtraSize; 42 1.1 kamil } 43 1.1 kamil // Use the other input data on the next iteration. 44 1.1 kamil InPos = CurrentlyUsingFirstData ? &Pos2 : &Pos1; 45 1.1 kamil InSize = CurrentlyUsingFirstData ? Size2 : Size1; 46 1.1 kamil Data = CurrentlyUsingFirstData ? Data2 : Data1; 47 1.1 kamil CurrentlyUsingFirstData = !CurrentlyUsingFirstData; 48 1.1 kamil } 49 1.1 kamil return OutPos; 50 1.1 kamil } 51 1.1 kamil 52 1.1 kamil } // namespace fuzzer 53