128e967aaSKostya Serebryany // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
228e967aaSKostya Serebryany // See https://llvm.org/LICENSE.txt for license information.
328e967aaSKostya Serebryany // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
428e967aaSKostya Serebryany
528e967aaSKostya Serebryany // Test for a fuzzer. The fuzzer must find the string
628e967aaSKostya Serebryany // ABCDEFGHIJ
7*c10e6367SDokyung Song // We use it as a test for each of CrossOver functionalities
8*c10e6367SDokyung Song // by passing the following sets of two inputs to it:
9*c10e6367SDokyung Song // {ABCDE00000, ZZZZZFGHIJ}
10*c10e6367SDokyung Song // {ABCDEHIJ, ZFG} to specifically test InsertPartOf
11*c10e6367SDokyung Song // {ABCDE00HIJ, ZFG} to specifically test CopyPartOf
1228e967aaSKostya Serebryany //
1328e967aaSKostya Serebryany #include <assert.h>
1428e967aaSKostya Serebryany #include <cstddef>
1528e967aaSKostya Serebryany #include <cstdint>
1628e967aaSKostya Serebryany #include <cstdlib>
1728e967aaSKostya Serebryany #include <iostream>
1828e967aaSKostya Serebryany #include <ostream>
1928e967aaSKostya Serebryany
2028e967aaSKostya Serebryany static volatile int Sink;
2128e967aaSKostya Serebryany static volatile int *NullPtr;
2228e967aaSKostya Serebryany
2328e967aaSKostya Serebryany // A modified jenkins_one_at_a_time_hash initialized by non-zero,
2428e967aaSKostya Serebryany // so that simple_hash(0) != 0. See also
2528e967aaSKostya Serebryany // https://en.wikipedia.org/wiki/Jenkins_hash_function
simple_hash(const uint8_t * Data,size_t Size)2628e967aaSKostya Serebryany static uint32_t simple_hash(const uint8_t *Data, size_t Size) {
2728e967aaSKostya Serebryany uint32_t Hash = 0x12039854;
2828e967aaSKostya Serebryany for (uint32_t i = 0; i < Size; i++) {
2928e967aaSKostya Serebryany Hash += Data[i];
3028e967aaSKostya Serebryany Hash += (Hash << 10);
3128e967aaSKostya Serebryany Hash ^= (Hash >> 6);
3228e967aaSKostya Serebryany }
3328e967aaSKostya Serebryany Hash += (Hash << 3);
3428e967aaSKostya Serebryany Hash ^= (Hash >> 11);
3528e967aaSKostya Serebryany Hash += (Hash << 15);
3628e967aaSKostya Serebryany return Hash;
3728e967aaSKostya Serebryany }
3828e967aaSKostya Serebryany
3928e967aaSKostya Serebryany // Don't leave the string in the binary, so that fuzzer don't cheat;
4028e967aaSKostya Serebryany // const char *ABC = "ABCDEFGHIJ";
4128e967aaSKostya Serebryany // static uint32_t ExpectedHash = simple_hash((const uint8_t *)ABC, 10);
4228e967aaSKostya Serebryany static const uint32_t ExpectedHash = 0xe1677acb;
4328e967aaSKostya Serebryany
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)4428e967aaSKostya Serebryany extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
4528e967aaSKostya Serebryany // fprintf(stderr, "ExpectedHash: %x\n", ExpectedHash);
46*c10e6367SDokyung Song if (Size == 10 && ExpectedHash == simple_hash(Data, Size))
47*c10e6367SDokyung Song *NullPtr = 0;
4828e967aaSKostya Serebryany if (*Data == 'A')
4928e967aaSKostya Serebryany Sink++;
5028e967aaSKostya Serebryany if (*Data == 'Z')
5128e967aaSKostya Serebryany Sink--;
5228e967aaSKostya Serebryany return 0;
5328e967aaSKostya Serebryany }
54