blob: bd9afe774d33c8d5340f34b41531b6b35cedd9b4 [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
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +00004// Simple test for a cutom crossover.
George Karpenkov10ab2ac2017-08-21 23:25:50 +00005#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>
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000013#include <functional>
George Karpenkov10ab2ac2017-08-21 23:25:50 +000014
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000015static const char *Separator = "-########-";
16static const char *Target = "A-########-B";
George Karpenkov10ab2ac2017-08-21 23:25:50 +000017
Kostya Serebryany754e5842017-09-07 05:33:05 +000018static volatile int sink;
19
George Karpenkov10ab2ac2017-08-21 23:25:50 +000020extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
21 assert(Data);
22 std::string Str(reinterpret_cast<const char *>(Data), Size);
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000023 static const size_t TargetHash = std::hash<std::string>{}(std::string(Target));
24 size_t StrHash = std::hash<std::string>{}(Str);
George Karpenkov10ab2ac2017-08-21 23:25:50 +000025
Kostya Serebryany754e5842017-09-07 05:33:05 +000026 // Ensure we have 'A' and 'B' in the corpus.
27 if (Size == 1 && *Data == 'A')
28 sink++;
29 if (Size == 1 && *Data == 'B')
30 sink--;
31
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000032 if (TargetHash == StrHash) {
George Karpenkov10ab2ac2017-08-21 23:25:50 +000033 std::cout << "BINGO; Found the target, exiting\n" << std::flush;
34 exit(1);
35 }
36 return 0;
37}
38
39extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
40 const uint8_t *Data2, size_t Size2,
41 uint8_t *Out, size_t MaxOutSize,
42 unsigned int Seed) {
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000043 static size_t Printed;
George Karpenkov10ab2ac2017-08-21 23:25:50 +000044 static size_t SeparatorLen = strlen(Separator);
45
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000046 if (Printed++ < 32)
47 std::cerr << "In LLVMFuzzerCustomCrossover " << Size1 << " " << Size2 << "\n";
George Karpenkov10ab2ac2017-08-21 23:25:50 +000048
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000049 size_t Size = Size1 + Size2 + SeparatorLen;
George Karpenkov10ab2ac2017-08-21 23:25:50 +000050
51 if (Size > MaxOutSize)
52 return 0;
53
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000054 memcpy(Out, Data1, Size1);
55 memcpy(Out + Size1, Separator, SeparatorLen);
56 memcpy(Out + Size1 + SeparatorLen, Data2, Size2);
George Karpenkov10ab2ac2017-08-21 23:25:50 +000057
Kostya Serebryanyd0386fa2017-09-07 02:04:06 +000058 return Size;
George Karpenkov10ab2ac2017-08-21 23:25:50 +000059}