1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11
10 
11 #include <algorithm>
12 #include <cstddef>
13 #include <cstdint>
14 #include <vector>
15 
16 #include "fuzz.h"
17 
LLVMFuzzerTestOneInput(const std::uint8_t * data,std::size_t size)18 extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
19     std::vector<std::uint8_t> working(data, data + size);
20     std::sort(working.begin(), working.end());
21     std::vector<std::uint8_t> results = working;
22     std::vector<std::uint8_t>::iterator new_end = std::unique(results.begin(), results.end());
23     std::vector<std::uint8_t>::iterator it; // scratch iterator
24 
25     // Check the size of the unique'd sequence.
26     // it should only be zero if the input sequence was empty.
27     if (results.begin() == new_end)
28         return working.size() == 0 ? 0 : 1;
29 
30     // 'results' is sorted
31     if (!std::is_sorted(results.begin(), new_end))
32         return 2;
33 
34     // All the elements in 'results' must be different
35     it = results.begin();
36     std::uint8_t prev_value = *it++;
37     for (; it != new_end; ++it) {
38         if (*it == prev_value)
39             return 3;
40         prev_value = *it;
41     }
42 
43     // Every element in 'results' must be in 'working'
44     for (it = results.begin(); it != new_end; ++it)
45         if (std::find(working.begin(), working.end(), *it) == working.end())
46             return 4;
47 
48     // Every element in 'working' must be in 'results'
49     for (auto v : working)
50         if (std::find(results.begin(), new_end, v) == new_end)
51             return 5;
52 
53     return 0;
54 }
55