Coverage Report

Created: 2024-06-28 06:19

/src/cryptofuzz/fuzzing-headers/include/fuzzing/datasource/datasource.hpp
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <fuzzing/exception.hpp>
4
#include <fuzzing/types.hpp>
5
#include <cstddef>
6
#include <cstdint>
7
#include <cstdlib>
8
#include <cstring>
9
#include <string>
10
#include <vector>
11
12
namespace fuzzing {
13
namespace datasource  {
14
15
class Base
16
{
17
    protected:
18
        virtual std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) = 0;
19
        virtual void put(const void* p, const size_t size, const uint64_t id = 0) = 0;
20
        std::vector<uint8_t> out;
21
    public:
22
77.0k
        Base(void) = default;
23
77.0k
        virtual ~Base(void) = default;
24
25
        template<class T> T Get(const uint64_t id = 0);
26
        template<class T> void Put(const T& v, const uint64_t id = 0);
27
28
        uint16_t GetChoice(const uint64_t id = 0);
29
30
        std::vector<uint8_t> GetData(const uint64_t id, const size_t min = 0, const size_t max = 0);
31
        void PutData(const std::vector<uint8_t>& data, const uint64_t id = 0);
32
33
        template <class T> std::vector<T> GetVector(const uint64_t id = 0);
34
0
        const std::vector<uint8_t>& GetOut(void) const { return out; }
35
36
        virtual size_t Left(void) const = 0;
37
38
        class OutOfData : public fuzzing::exception::FlowException {
39
            public:
40
10.3M
                OutOfData() = default;
41
        };
42
43
        class DeserializationFailure : public fuzzing::exception::FlowException {
44
            public:
45
                DeserializationFailure() = default;
46
        };
47
};
48
49
#ifndef FUZZING_HEADERS_NO_IMPL
50
template<class T> T Base::Get(const uint64_t id)
51
778k
{
52
778k
    T ret;
53
778k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
778k
    memcpy(&ret, v.data(), sizeof(ret));
55
778k
    return ret;
56
778k
}
unsigned long fuzzing::datasource::Base::Get<unsigned long>(unsigned long)
Line
Count
Source
51
623k
{
52
623k
    T ret;
53
623k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
623k
    memcpy(&ret, v.data(), sizeof(ret));
55
623k
    return ret;
56
623k
}
unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long)
Line
Count
Source
51
3.68k
{
52
3.68k
    T ret;
53
3.68k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
3.68k
    memcpy(&ret, v.data(), sizeof(ret));
55
3.68k
    return ret;
56
3.68k
}
unsigned int fuzzing::datasource::Base::Get<unsigned int>(unsigned long)
Line
Count
Source
51
33
{
52
33
    T ret;
53
33
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
33
    memcpy(&ret, v.data(), sizeof(ret));
55
33
    return ret;
56
33
}
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long)
Line
Count
Source
51
151k
{
52
151k
    T ret;
53
151k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
151k
    memcpy(&ret, v.data(), sizeof(ret));
55
151k
    return ret;
56
151k
}
unsigned char* fuzzing::datasource::Base::Get<unsigned char*>(unsigned long)
Line
Count
Source
51
38
{
52
38
    T ret;
53
38
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
38
    memcpy(&ret, v.data(), sizeof(ret));
55
38
    return ret;
56
38
}
57
58
template<class T> void Base::Put(const T& v, const uint64_t id)
59
0
{
60
0
    put(&v, sizeof(v), id);
61
0
}
Unexecuted instantiation: void fuzzing::datasource::Base::Put<unsigned char>(unsigned char const&, unsigned long)
Unexecuted instantiation: void fuzzing::datasource::Base::Put<unsigned int>(unsigned int const&, unsigned long)
Unexecuted instantiation: void fuzzing::datasource::Base::Put<unsigned long>(unsigned long const&, unsigned long)
62
63
template <> bool Base::Get<bool>(const uint64_t id)
64
10.5M
{
65
10.5M
    uint8_t ret;
66
10.5M
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
10.5M
    memcpy(&ret, v.data(), sizeof(ret));
68
10.5M
    return (ret % 2) ? true : false;
69
10.5M
}
70
71
template <> void Base::Put<bool>(const bool& v, const uint64_t id)
72
0
{
73
0
    const uint8_t _v = v ? 1 : 0;
74
0
    put(&_v, sizeof(_v), id);
75
0
}
76
77
template <> std::string Base::Get<std::string>(const uint64_t id)
78
0
{
79
0
    auto data = GetData(id);
80
0
    return std::string(data.data(), data.data() + data.size());
81
0
}
82
83
template <> std::vector<std::string> Base::Get<std::vector<std::string>>(const uint64_t id)
84
0
{
85
0
    std::vector<std::string> ret;
86
0
    while ( true ) {
87
0
        auto data = GetData(id);
88
0
        ret.push_back( std::string(data.data(), data.data() + data.size()) );
89
0
        if ( Get<bool>(id) == false ) {
90
0
            break;
91
0
        }
92
0
    }
93
0
    return ret;
94
0
}
95
96
uint16_t Base::GetChoice(const uint64_t id)
97
0
{
98
0
    return Get<uint16_t>(id);
99
0
}
100
101
std::vector<uint8_t> Base::GetData(const uint64_t id, const size_t min, const size_t max)
102
118k
{
103
118k
    return get(min, max, id);
104
118k
}
105
106
void Base::PutData(const std::vector<uint8_t>& data, const uint64_t id)
107
0
{
108
0
    return put(data.data(), data.size(), id);
109
0
}
110
111
0
template <> types::String<> Base::Get<types::String<>>(const uint64_t id) {
112
0
    const auto data = GetData(id);
113
0
    types::String<> ret(data.data(), data.size());
114
0
    return ret;
115
0
}
116
117
0
template <> types::Data<> Base::Get<types::Data<>>(const uint64_t id) {
118
0
    const auto data = GetData(id);
119
0
    types::Data<> ret(data.data(), data.size());
120
0
    return ret;
121
0
}
122
123
template <class T>
124
std::vector<T> Base::GetVector(const uint64_t id) {
125
    std::vector<T> ret;
126
127
    while ( Get<bool>(id) == true ) {
128
        ret.push_back( Get<T>(id) );
129
    }
130
131
    return ret;
132
}
133
#endif
134
135
class Datasource : public Base
136
{
137
    private:
138
        const uint8_t* data;
139
        const size_t size;
140
        size_t idx;
141
        size_t left;
142
        std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) override;
143
        void put(const void* p, const size_t size, const uint64_t id = 0) override;
144
    public:
145
        Datasource(const uint8_t* _data, const size_t _size);
146
        size_t Left(void) const override;
147
};
148
149
#ifndef FUZZING_HEADERS_NO_IMPL
150
Datasource::Datasource(const uint8_t* _data, const size_t _size) :
151
    Base(), data(_data), size(_size), idx(0), left(size)
152
77.0k
{
153
77.0k
}
154
155
11.3M
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
156
11.3M
    (void)id;
157
158
11.3M
    uint32_t getSize;
159
11.3M
    if ( left < sizeof(getSize) ) {
160
10.2M
        throw OutOfData();
161
10.2M
    }
162
1.11M
    memcpy(&getSize, data + idx, sizeof(getSize));
163
1.11M
    idx += sizeof(getSize);
164
1.11M
    left -= sizeof(getSize);
165
166
1.11M
    if ( getSize < min ) {
167
17.7k
        getSize = min;
168
17.7k
    }
169
1.11M
    if ( max && getSize > max ) {
170
964k
        getSize = max;
171
964k
    }
172
173
1.11M
    if ( left < getSize ) {
174
14.1k
        throw OutOfData();
175
14.1k
    }
176
177
1.09M
    std::vector<uint8_t> ret(getSize);
178
179
1.09M
    if ( getSize > 0 ) {
180
1.07M
        memcpy(ret.data(), data + idx, getSize);
181
1.07M
    }
182
1.09M
    idx += getSize;
183
1.09M
    left -= getSize;
184
185
1.09M
    return ret;
186
1.11M
}
187
188
0
void Datasource::put(const void* p, const size_t size, const uint64_t id) {
189
0
    (void)id;
190
0
    {
191
0
        const uint32_t _size = size;
192
0
        const auto oldSize = out.size();
193
0
        out.resize(oldSize + sizeof(_size) );
194
0
        memcpy(out.data() + oldSize, &_size, sizeof(_size));
195
0
    }
196
197
0
    {
198
0
        const auto oldSize = out.size();
199
0
        out.resize(oldSize + size);
200
0
        memcpy(out.data() + oldSize, p, size);
201
0
    }
202
0
}
203
204
0
size_t Datasource::Left(void) const {
205
0
    return left;
206
0
}
207
#endif
208
209
} /* namespace datasource */
210
} /* namespace fuzzing */