Coverage Report

Created: 2025-10-12 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/immer/extra/fuzzer/fuzzer_input.hpp
Line
Count
Source
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
#pragma once
10
11
#include <cstdint>
12
#include <memory>
13
#include <stdexcept>
14
15
#if defined(__GNUC__) && (__GNUC__ == 9 || __GNUC__ == 8 || __GNUC__ == 10)
16
#define IMMER_DISABLE_FUZZER_DUE_TO_GCC_BUG 1
17
#endif
18
19
struct no_more_input : std::exception
20
{};
21
22
constexpr auto fuzzer_input_max_size = 1 << 16;
23
24
struct fuzzer_input
25
{
26
    const std::uint8_t* data_;
27
    std::size_t size_;
28
29
    const std::uint8_t* next(std::size_t size)
30
1.04M
    {
31
1.04M
        if (size_ < size)
32
0
            throw no_more_input{};
33
1.04M
        auto r = data_;
34
1.04M
        data_ += size;
35
1.04M
        size_ -= size;
36
1.04M
        return r;
37
1.04M
    }
38
39
    const std::uint8_t* next(std::size_t size, std::size_t align)
40
1.05M
    {
41
1.05M
        auto& p = const_cast<void*&>(reinterpret_cast<const void*&>(data_));
42
1.05M
        auto r  = std::align(align, size, p, size_);
43
1.05M
        if (r == nullptr)
44
5.37k
            throw no_more_input{};
45
1.04M
        return next(size);
46
1.05M
    }
47
48
    template <typename Fn>
49
    int run(Fn step)
50
5.37k
    {
51
5.37k
        if (size_ > fuzzer_input_max_size)
52
5
            return 0;
53
5.37k
        try {
54
202k
            while (step(*this))
55
197k
                continue;
56
5.37k
        } catch (const no_more_input&) {
57
5.37k
        };
58
5.37k
        return 0;
59
5.37k
    }
60
};
61
62
template <typename T>
63
const T& read(fuzzer_input& fz)
64
1.05M
{
65
1.05M
    return *reinterpret_cast<const T*>(fz.next(sizeof(T), alignof(T)));
66
1.05M
}
char const& read<char>(fuzzer_input&)
Line
Count
Source
64
891k
{
65
891k
    return *reinterpret_cast<const T*>(fz.next(sizeof(T), alignof(T)));
66
891k
}
unsigned long const& read<unsigned long>(fuzzer_input&)
Line
Count
Source
64
159k
{
65
159k
    return *reinterpret_cast<const T*>(fz.next(sizeof(T), alignof(T)));
66
159k
}
67
68
template <typename T, typename Cond>
69
T read(fuzzer_input& fz, Cond cond)
70
400k
{
71
400k
    auto x = read<T>(fz);
72
693k
    while (!cond(x))
73
293k
        x = read<T>(fz);
74
400k
    return x;
75
400k
}