]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/beast/test/extras/include/boost/beast/test/fuzz.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / beast / test / extras / include / boost / beast / test / fuzz.hpp
CommitLineData
b32b8144 1//
92f5a8d4 2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
b32b8144
FG
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
17namespace boost {
18namespace beast {
19namespace test {
20
21class fuzz_rand
22{
23 std::mt19937 rng_;
24
25public:
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
42template<std::size_t N, class Rand, class F>
43static
44void
45fuzz(
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