1//
2// immer: immutable data structures for C++
3// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
4//
5// This software is distributed under the Boost Software License, Version 1.0.
6// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
7//
8
9#include "fuzzer_input.hpp"
10#include <immer/vector.hpp>
11#include <iostream>
12#include <array>
13
14extern "C"
15int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size)
16{
17 constexpr auto var_count = 4;
18 constexpr auto bits = 2;
19
20 using vector_t = immer::vector<int, immer::default_memory_policy, bits, bits>;
21 using size_t = std::uint8_t;
22
23 auto vars = std::array<vector_t, var_count>{};
24
25 auto is_valid_var = [&] (auto idx) {
26 return idx >= 0 && idx < var_count;
27 };
28 auto is_valid_index = [] (auto& v) {
29 return [&] (auto idx) { return idx >= 0 && idx < v.size(); };
30 };
31 auto is_valid_size = [] (auto& v) {
32 return [&] (auto idx) { return idx >= 0 && idx <= v.size(); };
33 };
34
35 return fuzzer_input{data, size}.run([&] (auto& in)
36 {
37 enum ops {
38 op_push_back,
39 op_update,
40 op_take,
41 op_push_back_move,
42 op_update_move,
43 op_take_move,
44 };
45 auto src = read<char>(in, is_valid_var);
46 auto dst = read<char>(in, is_valid_var);
47 switch (read<char>(in))
48 {
49 case op_push_back: {
50 vars[dst] = vars[src].push_back(42);
51 break;
52 }
53 case op_update: {
54 auto idx = read<size_t>(in, is_valid_index(vars[src]));
55 vars[dst] = vars[src].update(idx, [] (auto x) { return x + 1; });
56 break;
57 }
58 case op_take: {
59 auto idx = read<size_t>(in, is_valid_size(vars[src]));
60 vars[dst] = vars[src].take(idx);
61 break;
62 }
63 case op_push_back_move: {
64 vars[dst] = std::move(vars[src]).push_back(12);
65 break;
66 }
67 case op_update_move: {
68 auto idx = read<size_t>(in, is_valid_index(vars[src]));
69 vars[dst] = std::move(vars[src])
70 .update(idx, [] (auto x) { return x + 1; });
71 break;
72 }
73 case op_take_move: {
74 auto idx = read<size_t>(in, is_valid_size(vars[src]));
75 vars[dst] = std::move(vars[src]).take(idx);
76 break;
77 }
78 default:
79 break;
80 };
81 return true;
82 });
83}
84