Skip to content

Commit 7ec1c5c

Browse files
committed
Remove too-simple test, add tests for the variants of minmax_element
1 parent d574d1e commit 7ec1c5c

File tree

3 files changed

+161
-64
lines changed

3 files changed

+161
-64
lines changed

minmax/fuzzing/minmax.fuzz.cpp

Lines changed: 0 additions & 52 deletions
This file was deleted.

minmax/fuzzing/minmax_element.fuzz.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
55

66
#include <iterator> // for std::distance
7+
#include <cassert> // for assert
78

89
#include <boost/algorithm/minmax_element.hpp>
10+
#include <boost/algorithm/cxx11/none_of.hpp>
911

1012
// Fuzzing tests for:
1113
//
@@ -29,42 +31,50 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz) {
2931
// Find the min and max
3032
result_t result = boost::minmax_element(data, data + sz);
3133

32-
// The iterators have to be in the sequence
33-
if (std::distance(data, result.first) >= sz) return 1;
34-
if (std::distance(data, result.second) >= sz) return 1;
34+
// The iterators have to be in the sequence - and not at the end!
35+
assert(std::distance(data, result.first) < sz);
36+
assert(std::distance(data, result.second) < sz);
3537

3638
// the minimum element can't be bigger than the max element
3739
uint8_t min_value = *result.first;
3840
uint8_t max_value = *result.second;
3941

40-
if (max_value < min_value) return 2;
42+
assert(min_value <= max_value);
4143

4244
// None of the elements in the sequence can be less than the min, nor greater than the max
4345
for (size_t i = 0; i < sz; ++i) {
44-
if (data[i] < min_value) return 3;
45-
if (max_value < data[i]) return 3;
46+
assert(min_value <= data[i]);
47+
assert(data[i] <= max_value);
4648
}
49+
50+
// We returned the first min element, and the first max element
51+
assert(boost::algorithm::none_of_equal(data, result.first, min_value));
52+
assert(boost::algorithm::none_of_equal(data, result.second, max_value));
4753
}
4854

4955
{
5056
// Find the min and max
5157
result_t result = boost::minmax_element(data, data + sz, greater);
5258

53-
// The iterators have to be in the sequence
54-
if (std::distance(data, result.first) >= sz) return 1;
55-
if (std::distance(data, result.second) >= sz) return 1;
59+
// The iterators have to be in the sequence - and not at the end!
60+
assert(std::distance(data, result.first) < sz);
61+
assert(std::distance(data, result.second) < sz);
5662

5763
// the minimum element can't be bigger than the max element
5864
uint8_t min_value = *result.first;
5965
uint8_t max_value = *result.second;
6066

61-
if (greater(max_value, min_value)) return 2;
67+
assert (!greater(max_value, min_value));
6268

6369
// None of the elements in the sequence can be less than the min, nor greater than the max
6470
for (size_t i = 0; i < sz; ++i) {
65-
if (greater(data[i], min_value)) return 3;
66-
if (greater(max_value, data[i])) return 3;
71+
assert(!greater(data[i], min_value));
72+
assert(!greater(max_value, data[i]));
6773
}
74+
75+
// We returned the first min element, and the first max element
76+
assert(boost::algorithm::none_of_equal(data, result.first, min_value));
77+
assert(boost::algorithm::none_of_equal(data, result.second, max_value));
6878
}
6979

7080
return 0;
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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

Comments
 (0)