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