blob: 58059c9c1ebc8edbcf2aeafa662622190af8b742 [file] [log] [blame]
George Karpenkov10ab2ac2017-08-21 23:25:50 +00001// This file is distributed under the University of Illinois Open Source
2// License. See LICENSE.TXT for details.
3
4// Simple test for a cutom mutator.
5#include <assert.h>
6#include <cstddef>
7#include <cstdint>
8#include <cstdlib>
9#include <iostream>
10#include <ostream>
11#include <random>
12#include <string.h>
13
14#include "FuzzerInterface.h"
15
16static const char *Separator = "-_^_-";
17static const char *Target = "012-_^_-abc";
18
19static volatile int sink;
20
21extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
22 assert(Data);
23 std::string Str(reinterpret_cast<const char *>(Data), Size);
24
25 // Ensure that two different elements exist in the corpus.
26 if (Size && Data[0] == '0') sink++;
27 if (Size && Data[0] == 'a') sink--;
28
29 if (Str.find(Target) != std::string::npos) {
30 std::cout << "BINGO; Found the target, exiting\n" << std::flush;
31 exit(1);
32 }
33 return 0;
34}
35
36extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
37 const uint8_t *Data2, size_t Size2,
38 uint8_t *Out, size_t MaxOutSize,
39 unsigned int Seed) {
40 static bool Printed;
41 static size_t SeparatorLen = strlen(Separator);
42
43 if (!Printed) {
44 std::cerr << "In LLVMFuzzerCustomCrossover\n";
45 Printed = true;
46 }
47
48 std::mt19937 R(Seed);
49
50 size_t Offset1 = 0;
51 size_t Len1 = R() % (Size1 - Offset1);
52 size_t Offset2 = 0;
53 size_t Len2 = R() % (Size2 - Offset2);
54 size_t Size = Len1 + Len2 + SeparatorLen;
55
56 if (Size > MaxOutSize)
57 return 0;
58
59 memcpy(Out, Data1 + Offset1, Len1);
60 memcpy(Out + Len1, Separator, SeparatorLen);
61 memcpy(Out + Len1 + SeparatorLen, Data2 + Offset2, Len2);
62
63 return Len1 + Len2 + SeparatorLen;
64}