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/array.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
19 using array_t= immer::array<int, immer::default_memory_policy>;
20 using size_t = std::uint8_t;
21
22 auto vars = std::array<array_t, var_count>{};
23
24 auto is_valid_var = [&] (auto idx) {
25 return idx >= 0 && idx < var_count;
26 };
27 auto is_valid_index = [] (auto& v) {
28 return [&] (auto idx) { return idx >= 0 && idx < v.size(); };
29 };
30 auto is_valid_size = [] (auto& v) {
31 return [&] (auto idx) { return idx >= 0 && idx <= v.size(); };
32 };
33
34 return fuzzer_input{data, size}.run([&] (auto& in)
35 {
36 enum ops {
37 op_push_back,
38 op_update,
39 op_take,
40 op_push_back_move,
41 op_update_move,
42 op_take_move,
43 };
44 auto src = read<char>(in, is_valid_var);
45 auto dst = read<char>(in, is_valid_var);
46 switch (read<char>(in))
47 {
48 case op_push_back: {
49 vars[dst] = vars[src].push_back(42);
50 break;
51 }
52 case op_update: {
53 auto idx = read<size_t>(in, is_valid_index(vars[src]));
54 vars[dst] = vars[src].update(idx, [] (auto x) { return x + 1; });
55 break;
56 }
57 case op_take: {
58 auto idx = read<size_t>(in, is_valid_size(vars[src]));
59 vars[dst] = vars[src].take(idx);
60 break;
61 }
62 case op_push_back_move: {
63 vars[dst] = std::move(vars[src]).push_back(12);
64 break;
65 }
66 case op_update_move: {
67 auto idx = read<size_t>(in, is_valid_index(vars[src]));
68 vars[dst] = std::move(vars[src])
69 .update(idx, [] (auto x) { return x + 1; });
70 break;
71 }
72 case op_take_move: {
73 auto idx = read<size_t>(in, is_valid_size(vars[src]));
74 vars[dst] = std::move(vars[src]).take(idx);
75 break;
76 }
77 default:
78 break;
79 };
80 return true;
81 });
82}
83