]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/extras/include/boost/beast/test/fuzz.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / test / extras / include / boost / beast / test / fuzz.hpp
1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_TEST_FUZZ_HPP
11 #define BOOST_BEAST_TEST_FUZZ_HPP
12
13 #include <boost/beast/core/static_string.hpp>
14 #include <boost/beast/core/string.hpp>
15 #include <random>
16
17 namespace boost {
18 namespace beast {
19 namespace test {
20
21 class fuzz_rand
22 {
23 std::mt19937 rng_;
24
25 public:
26 std::mt19937&
27 rng()
28 {
29 return rng_;
30 }
31
32 template<class Unsigned>
33 Unsigned
34 operator()(Unsigned n)
35 {
36 return static_cast<Unsigned>(
37 std::uniform_int_distribution<
38 Unsigned>{0, n-1}(rng_));
39 }
40 };
41
42 template<std::size_t N, class Rand, class F>
43 static
44 void
45 fuzz(
46 static_string<N> const& input,
47 std::size_t repeat,
48 std::size_t depth,
49 Rand& r,
50 F const& f)
51 {
52 static_string<N> mod{input};
53 for(auto i = repeat; i; --i)
54 {
55 switch(r(4))
56 {
57 case 0: // insert
58 if(mod.size() >= mod.max_size())
59 continue;
60 mod.insert(r(mod.size() + 1), 1,
61 static_cast<char>(r(256)));
62 break;
63
64 case 1: // erase
65 if(mod.size() == 0)
66 continue;
67 mod.erase(r(mod.size()), 1);
68 break;
69
70 case 2: // swap
71 {
72 if(mod.size() <= 1)
73 continue;
74 auto off = r(mod.size() - 1);
75 auto const temp = mod[off];
76 mod[off] = mod[off + 1];
77 mod[off + 1] = temp;
78 break;
79 }
80 case 3: // repeat
81 {
82 if(mod.empty())
83 continue;
84 auto n = (std::min)(
85 std::geometric_distribution<
86 std::size_t>{}(r.rng()),
87 mod.max_size() - mod.size());
88 if(n == 0)
89 continue;
90 auto off = r(mod.size());
91 mod.insert(off, n, mod[off + 1]);
92 break;
93 }
94 }
95 f(string_view{mod.data(), mod.size()});
96 if(depth > 0)
97 fuzz(mod, repeat, depth - 1, r, f);
98 }
99 }
100
101 } // test
102 } // beast
103 } // boost
104
105 #endif