12946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
22946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
32946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
410ab2aceSGeorge Karpenkov
5*a1e7e401SKazuaki Ishizaki // Simple test for a custom crossover.
610ab2aceSGeorge Karpenkov #include <assert.h>
710ab2aceSGeorge Karpenkov #include <cstddef>
810ab2aceSGeorge Karpenkov #include <cstdint>
910ab2aceSGeorge Karpenkov #include <cstdlib>
1010ab2aceSGeorge Karpenkov #include <iostream>
1110ab2aceSGeorge Karpenkov #include <ostream>
1210ab2aceSGeorge Karpenkov #include <random>
1310ab2aceSGeorge Karpenkov #include <string.h>
14d0386facSKostya Serebryany #include <functional>
1510ab2aceSGeorge Karpenkov
16d0386facSKostya Serebryany static const char *Separator = "-########-";
17d0386facSKostya Serebryany static const char *Target = "A-########-B";
1810ab2aceSGeorge Karpenkov
19754e5840SKostya Serebryany static volatile int sink;
20754e5840SKostya Serebryany
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)2110ab2aceSGeorge Karpenkov extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
2210ab2aceSGeorge Karpenkov assert(Data);
2310ab2aceSGeorge Karpenkov std::string Str(reinterpret_cast<const char *>(Data), Size);
24d0386facSKostya Serebryany static const size_t TargetHash = std::hash<std::string>{}(std::string(Target));
25d0386facSKostya Serebryany size_t StrHash = std::hash<std::string>{}(Str);
2610ab2aceSGeorge Karpenkov
27754e5840SKostya Serebryany // Ensure we have 'A' and 'B' in the corpus.
28754e5840SKostya Serebryany if (Size == 1 && *Data == 'A')
29754e5840SKostya Serebryany sink++;
30754e5840SKostya Serebryany if (Size == 1 && *Data == 'B')
31754e5840SKostya Serebryany sink--;
32754e5840SKostya Serebryany
33d0386facSKostya Serebryany if (TargetHash == StrHash) {
3410ab2aceSGeorge Karpenkov std::cout << "BINGO; Found the target, exiting\n" << std::flush;
3510ab2aceSGeorge Karpenkov exit(1);
3610ab2aceSGeorge Karpenkov }
3710ab2aceSGeorge Karpenkov return 0;
3810ab2aceSGeorge Karpenkov }
3910ab2aceSGeorge Karpenkov
LLVMFuzzerCustomCrossOver(const uint8_t * Data1,size_t Size1,const uint8_t * Data2,size_t Size2,uint8_t * Out,size_t MaxOutSize,unsigned int Seed)4010ab2aceSGeorge Karpenkov extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
4110ab2aceSGeorge Karpenkov const uint8_t *Data2, size_t Size2,
4210ab2aceSGeorge Karpenkov uint8_t *Out, size_t MaxOutSize,
4310ab2aceSGeorge Karpenkov unsigned int Seed) {
44d0386facSKostya Serebryany static size_t Printed;
4510ab2aceSGeorge Karpenkov static size_t SeparatorLen = strlen(Separator);
4610ab2aceSGeorge Karpenkov
47d0386facSKostya Serebryany if (Printed++ < 32)
48d0386facSKostya Serebryany std::cerr << "In LLVMFuzzerCustomCrossover " << Size1 << " " << Size2 << "\n";
4910ab2aceSGeorge Karpenkov
50d0386facSKostya Serebryany size_t Size = Size1 + Size2 + SeparatorLen;
5110ab2aceSGeorge Karpenkov
5210ab2aceSGeorge Karpenkov if (Size > MaxOutSize)
5310ab2aceSGeorge Karpenkov return 0;
5410ab2aceSGeorge Karpenkov
55d0386facSKostya Serebryany memcpy(Out, Data1, Size1);
56d0386facSKostya Serebryany memcpy(Out + Size1, Separator, SeparatorLen);
57d0386facSKostya Serebryany memcpy(Out + Size1 + SeparatorLen, Data2, Size2);
5810ab2aceSGeorge Karpenkov
59d0386facSKostya Serebryany return Size;
6010ab2aceSGeorge Karpenkov }
61