1+ // (C) Copyright Marshall Clow 2018
2+ // Use, modification and distribution are subject to the
3+ // Boost Software License, Version 1.0. (See accompanying file
4+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+ #include < iterator> // for std::distance
7+ #include < cassert> // for assert
8+
9+ #include < boost/algorithm/minmax_element.hpp>
10+ #include < boost/algorithm/cxx11/none_of.hpp>
11+
12+ // Fuzzing tests for:
13+ //
14+ // template <class ForwardIterator>
15+ // std::pair<ForwardIterator,ForwardIterator>
16+ // first_min_first_max_element(ForwardIterator first, ForwardIterator last);
17+ //
18+ // template <class ForwardIterator, class BinaryPredicate>
19+ // std::pair<ForwardIterator,ForwardIterator>
20+ // first_min_first_max_element(ForwardIterator first, ForwardIterator last,
21+ // BinaryPredicate comp);
22+ //
23+ // identical signatures for:
24+ // first_min_last_max_element
25+ // last_min_first_max_element
26+ // last_min_last_max_element
27+
28+ bool greater (uint8_t lhs, uint8_t rhs) { return lhs > rhs; }
29+
30+ extern " C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t sz) {
31+ typedef std::pair<const uint8_t *, const uint8_t *> result_t ;
32+ const uint8_t * const dend = data + sz;
33+ if (sz == 0 ) return 0 ; // we need at least one element
34+
35+ {
36+ // Find the min and max
37+ result_t resultff = boost::first_min_first_max_element (data, dend);
38+ result_t resultfl = boost::first_min_last_max_element (data, dend);
39+ result_t resultlf = boost::last_min_first_max_element (data, dend);
40+ result_t resultll = boost::last_min_last_max_element (data, dend);
41+
42+ // The iterators have to be in the sequence - and not at the end!
43+ assert (std::distance (data, resultff.first ) < sz);
44+ assert (std::distance (data, resultff.second ) < sz);
45+ assert (std::distance (data, resultfl.first ) < sz);
46+ assert (std::distance (data, resultfl.second ) < sz);
47+ assert (std::distance (data, resultlf.first ) < sz);
48+ assert (std::distance (data, resultlf.second ) < sz);
49+ assert (std::distance (data, resultll.first ) < sz);
50+ assert (std::distance (data, resultll.second ) < sz);
51+
52+ // the minimum element can't be bigger than the max element
53+
54+ // Did we find the same min value and max value?
55+ uint8_t min_value = *resultff.first ;
56+ uint8_t max_value = *resultff.second ;
57+ assert (min_value <= max_value);
58+
59+ assert (*resultff.first == min_value);
60+ assert (*resultfl.first == min_value);
61+ assert (*resultlf.first == min_value);
62+ assert (*resultll.first == min_value);
63+
64+ assert (*resultff.second == max_value);
65+ assert (*resultfl.second == max_value);
66+ assert (*resultlf.second == max_value);
67+ assert (*resultll.second == max_value);
68+
69+ // None of the elements in the sequence can be less than the min, nor greater than the max
70+ for (size_t i = 0 ; i < sz; ++i) {
71+ assert (min_value <= data[i]);
72+ assert (data[i] <= max_value);
73+ }
74+
75+ // Make sure we returned the "right" first and last element
76+ assert (boost::algorithm::none_of_equal (data, resultff.first , min_value));
77+ assert (boost::algorithm::none_of_equal (data, resultfl.first , min_value));
78+ assert (boost::algorithm::none_of_equal (resultlf.first + 1 , dend, min_value));
79+ assert (boost::algorithm::none_of_equal (resultll.first + 1 , dend, min_value));
80+
81+ assert (boost::algorithm::none_of_equal (data, resultff.second , max_value));
82+ assert (boost::algorithm::none_of_equal (resultfl.second + 1 , dend, max_value));
83+ assert (boost::algorithm::none_of_equal (data, resultlf.second , max_value));
84+ assert (boost::algorithm::none_of_equal (resultll.second + 1 , dend, max_value));
85+ }
86+
87+ {
88+ // Find the min and max
89+ result_t resultff = boost::first_min_first_max_element (data, dend, greater);
90+ result_t resultfl = boost::first_min_last_max_element (data, dend, greater);
91+ result_t resultlf = boost::last_min_first_max_element (data, dend, greater);
92+ result_t resultll = boost::last_min_last_max_element (data, dend, greater);
93+
94+ // The iterators have to be in the sequence - and not at the end!
95+ assert (std::distance (data, resultff.first ) < sz);
96+ assert (std::distance (data, resultff.second ) < sz);
97+ assert (std::distance (data, resultfl.first ) < sz);
98+ assert (std::distance (data, resultfl.second ) < sz);
99+ assert (std::distance (data, resultlf.first ) < sz);
100+ assert (std::distance (data, resultlf.second ) < sz);
101+ assert (std::distance (data, resultll.first ) < sz);
102+ assert (std::distance (data, resultll.second ) < sz);
103+
104+ // the minimum element can't be bigger than the max element
105+ uint8_t min_value = *resultff.first ;
106+ uint8_t max_value = *resultff.second ;
107+
108+ assert (!greater (max_value, min_value));
109+
110+ assert (*resultff.first == min_value);
111+ assert (*resultfl.first == min_value);
112+ assert (*resultlf.first == min_value);
113+ assert (*resultll.first == min_value);
114+
115+ assert (*resultff.second == max_value);
116+ assert (*resultfl.second == max_value);
117+ assert (*resultlf.second == max_value);
118+ assert (*resultll.second == max_value);
119+
120+ // None of the elements in the sequence can be less than the min, nor greater than the max
121+ for (size_t i = 0 ; i < sz; ++i) {
122+ assert (!greater (data[i], min_value));
123+ assert (!greater (max_value, data[i]));
124+ }
125+
126+ // We returned the first min element, and the first max element
127+ assert (boost::algorithm::none_of_equal (data, resultff.first , min_value));
128+ assert (boost::algorithm::none_of_equal (data, resultfl.first , min_value));
129+ assert (boost::algorithm::none_of_equal (resultlf.first + 1 , dend, min_value));
130+ assert (boost::algorithm::none_of_equal (resultll.first + 1 , dend, min_value));
131+
132+ assert (boost::algorithm::none_of_equal (data, resultff.second , max_value));
133+ assert (boost::algorithm::none_of_equal (resultfl.second + 1 , dend, max_value));
134+ assert (boost::algorithm::none_of_equal (data, resultlf.second , max_value));
135+ assert (boost::algorithm::none_of_equal (resultll.second + 1 , dend, max_value));
136+ }
137+
138+ return 0 ;
139+ }
0 commit comments