Coverage Report

Created: 2023-02-22 06:39

/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
48.6k
        Base(void) = default;
23
48.6k
        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
12.2M
                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
128k
{
52
128k
    T ret;
53
128k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
128k
    memcpy(&ret, v.data(), sizeof(ret));
55
128k
    return ret;
56
128k
}
unsigned long fuzzing::datasource::Base::Get<unsigned long>(unsigned long)
Line
Count
Source
51
50.0k
{
52
50.0k
    T ret;
53
50.0k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
50.0k
    memcpy(&ret, v.data(), sizeof(ret));
55
50.0k
    return ret;
56
50.0k
}
unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long)
Line
Count
Source
51
1.46k
{
52
1.46k
    T ret;
53
1.46k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
1.46k
    memcpy(&ret, v.data(), sizeof(ret));
55
1.46k
    return ret;
56
1.46k
}
unsigned int fuzzing::datasource::Base::Get<unsigned int>(unsigned long)
Line
Count
Source
51
32
{
52
32
    T ret;
53
32
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
32
    memcpy(&ret, v.data(), sizeof(ret));
55
32
    return ret;
56
32
}
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long)
Line
Count
Source
51
76.4k
{
52
76.4k
    T ret;
53
76.4k
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
76.4k
    memcpy(&ret, v.data(), sizeof(ret));
55
76.4k
    return ret;
56
76.4k
}
unsigned char* fuzzing::datasource::Base::Get<unsigned char*>(unsigned long)
Line
Count
Source
51
34
{
52
34
    T ret;
53
34
    const auto v = get(sizeof(ret), sizeof(ret), id);
54
34
    memcpy(&ret, v.data(), sizeof(ret));
55
34
    return ret;
56
34
}
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
12.3M
{
65
12.3M
    uint8_t ret;
66
12.3M
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
12.3M
    memcpy(&ret, v.data(), sizeof(ret));
68
12.3M
    return (ret % 2) ? true : false;
69
12.3M
}
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
87.1k
{
103
87.1k
    return get(min, max, id);
104
87.1k
}
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
48.6k
{
153
48.6k
}
154
155
12.5M
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
156
12.5M
    (void)id;
157
158
12.5M
    uint32_t getSize;
159
12.5M
    if ( left < sizeof(getSize) ) {
160
12.2M
        throw OutOfData();
161
12.2M
    }
162
346k
    memcpy(&getSize, data + idx, sizeof(getSize));
163
346k
    idx += sizeof(getSize);
164
346k
    left -= sizeof(getSize);
165
166
346k
    if ( getSize < min ) {
167
15.8k
        getSize = min;
168
15.8k
    }
169
346k
    if ( max && getSize > max ) {
170
250k
        getSize = max;
171
250k
    }
172
173
346k
    if ( left < getSize ) {
174
10.6k
        throw OutOfData();
175
10.6k
    }
176
177
335k
    std::vector<uint8_t> ret(getSize);
178
179
335k
    if ( getSize > 0 ) {
180
321k
        memcpy(ret.data(), data + idx, getSize);
181
321k
    }
182
335k
    idx += getSize;
183
335k
    left -= getSize;
184
185
335k
    return ret;
186
346k
}
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 */