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