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/map.hpp>
11#include <immer/heap/gc_heap.hpp>
12#include <immer/refcount/no_refcount_policy.hpp>
13#include <iostream>
14#include <array>
15
16using gc_memory = immer::memory_policy<
17 immer::heap_policy<immer::gc_heap>,
18 immer::no_refcount_policy,
19 immer::gc_transience_policy,
20 false>;
21
22extern "C"
23int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size)
24{
25 constexpr auto var_count = 4;
26
27 using map_t = immer::map<char, int, std::hash<char>, std::equal_to<char>, gc_memory>;
28
29 auto vars = std::array<map_t, var_count>{};
30
31 auto is_valid_var = [&] (auto idx) {
32 return idx >= 0 && idx < var_count;
33 };
34
35 return fuzzer_input{data, size}.run([&] (auto& in)
36 {
37 enum ops {
38 op_set,
39 op_erase,
40 op_set_move,
41 op_erase_move,
42 op_iterate,
43 op_find,
44 op_update
45 };
46 auto src = read<char>(in, is_valid_var);
47 auto dst = read<char>(in, is_valid_var);
48 switch (read<char>(in))
49 {
50 case op_set: {
51 auto value = read<size_t>(in);
52 vars[dst] = vars[src].set(value, 42);
53 break;
54 }
55 case op_erase: {
56 auto value = read<size_t>(in);
57 vars[dst] = vars[src].erase(value);
58 break;
59 }
60 case op_set_move: {
61 auto value = read<size_t>(in);
62 vars[dst] = std::move(vars[src]).set(value, 42);
63 break;
64 }
65 case op_erase_move: {
66 auto value = read<size_t>(in);
67 vars[dst] = std::move(vars[src]).erase(value);
68 break;
69 }
70 case op_iterate: {
71 auto srcv = vars[src];
72 for(const auto& v : srcv) {
73 vars[dst] = vars[dst].set(v.first, v.second);
74 }
75 break;
76 }
77 case op_find: {
78 auto value = read<size_t>(in);
79 auto res = vars[src].find(value);
80 if(res != nullptr) {
81 vars[dst] = vars[dst].set(*res, 42);
82 }
83 break;
84 }
85 case op_update: {
86 auto key = read<size_t>(in);
87 vars[dst] = vars[src].update(key, [](int x) { return x+1; });
88 break;
89 }
90 default:
91 break;
92 };
93 return true;
94 });
95}
96