Coverage Report

Created: 2023-06-07 06:14

/src/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
    public:
20
811
        Base(void) = default;
21
811
        virtual ~Base(void) = default;
22
23
        template<class T> T Get(const uint64_t id = 0);
24
        uint16_t GetChoice(const uint64_t id = 0);
25
        std::vector<uint8_t> GetData(const uint64_t id, const size_t min = 0, const size_t max = 0);
26
        template <class T> std::vector<T> GetVector(const uint64_t id = 0);
27
28
        class OutOfData : public fuzzing::exception::FlowException {
29
            public:
30
1.52k
                OutOfData() = default;
31
        };
32
33
        class DeserializationFailure : public fuzzing::exception::FlowException {
34
            public:
35
                DeserializationFailure() = default;
36
        };
37
};
38
39
#ifndef FUZZING_HEADERS_NO_IMPL
40
template<class T> T Base::Get(const uint64_t id)
41
9.50k
{
42
9.50k
    T ret;
43
9.50k
    const auto v = get(sizeof(ret), sizeof(ret), id);
44
9.50k
    memcpy(&ret, v.data(), sizeof(ret));
45
9.50k
    return ret;
46
9.50k
}
unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long)
Line
Count
Source
41
2.85k
{
42
2.85k
    T ret;
43
2.85k
    const auto v = get(sizeof(ret), sizeof(ret), id);
44
2.85k
    memcpy(&ret, v.data(), sizeof(ret));
45
2.85k
    return ret;
46
2.85k
}
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long)
Line
Count
Source
41
4.06k
{
42
4.06k
    T ret;
43
4.06k
    const auto v = get(sizeof(ret), sizeof(ret), id);
44
4.06k
    memcpy(&ret, v.data(), sizeof(ret));
45
4.06k
    return ret;
46
4.06k
}
unsigned int fuzzing::datasource::Base::Get<unsigned int>(unsigned long)
Line
Count
Source
41
2.59k
{
42
2.59k
    T ret;
43
2.59k
    const auto v = get(sizeof(ret), sizeof(ret), id);
44
2.59k
    memcpy(&ret, v.data(), sizeof(ret));
45
2.59k
    return ret;
46
2.59k
}
47
48
template <> bool Base::Get<bool>(const uint64_t id)
49
5.67k
{
50
5.67k
    uint8_t ret;
51
5.67k
    const auto v = get(sizeof(ret), sizeof(ret), id);
52
5.67k
    memcpy(&ret, v.data(), sizeof(ret));
53
5.67k
    return (ret % 2) ? true : false;
54
5.67k
}
55
56
template <> std::string Base::Get<std::string>(const uint64_t id)
57
2.38k
{
58
2.38k
    auto data = GetData(id);
59
2.38k
    return std::string(data.data(), data.data() + data.size());
60
2.38k
}
61
62
template <> std::vector<std::string> Base::Get<std::vector<std::string>>(const uint64_t id)
63
0
{
64
0
    std::vector<std::string> ret;
65
0
    while ( true ) {
66
0
        auto data = GetData(id);
67
0
        ret.push_back( std::string(data.data(), data.data() + data.size()) );
68
0
        if ( Get<bool>(id) == false ) {
69
0
            break;
70
0
        }
71
0
    }
72
0
    return ret;
73
0
}
74
75
uint16_t Base::GetChoice(const uint64_t id)
76
0
{
77
0
    return Get<uint16_t>(id);
78
0
}
79
80
std::vector<uint8_t> Base::GetData(const uint64_t id, const size_t min, const size_t max)
81
13.0k
{
82
13.0k
    return get(min, max, id);
83
13.0k
}
84
85
86
0
template <> types::String<> Base::Get<types::String<>>(const uint64_t id) {
87
0
    const auto data = GetData(id);
88
0
    types::String<> ret(data.data(), data.size());
89
0
    return ret;
90
0
}
91
92
0
template <> types::Data<> Base::Get<types::Data<>>(const uint64_t id) {
93
0
    const auto data = GetData(id);
94
0
    types::Data<> ret(data.data(), data.size());
95
0
    return ret;
96
0
}
97
98
template <class T>
99
std::vector<T> Base::GetVector(const uint64_t id) {
100
    std::vector<T> ret;
101
102
    while ( Get<bool>(id) == true ) {
103
        ret.push_back( Get<T>(id) );
104
    }
105
106
    return ret;
107
}
108
#endif
109
110
class Datasource : public Base
111
{
112
    private:
113
        const uint8_t* data;
114
        const size_t size;
115
        size_t idx;
116
        size_t left;
117
        std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) override;
118
    public:
119
        Datasource(const uint8_t* _data, const size_t _size);
120
};
121
122
#ifndef FUZZING_HEADERS_NO_IMPL
123
Datasource::Datasource(const uint8_t* _data, const size_t _size) :
124
    Base(), data(_data), size(_size), idx(0), left(size)
125
811
{
126
811
}
127
128
28.2k
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
129
28.2k
    (void)id;
130
131
28.2k
    uint32_t getSize;
132
28.2k
    if ( left < sizeof(getSize) ) {
133
1.03k
        throw OutOfData();
134
1.03k
    }
135
27.1k
    memcpy(&getSize, data + idx, sizeof(getSize));
136
27.1k
    idx += sizeof(getSize);
137
27.1k
    left -= sizeof(getSize);
138
139
27.1k
    if ( getSize < min ) {
140
3.75k
        getSize = min;
141
3.75k
    }
142
27.1k
    if ( max && getSize > max ) {
143
10.5k
        getSize = max;
144
10.5k
    }
145
146
27.1k
    if ( left < getSize ) {
147
486
        throw OutOfData();
148
486
    }
149
150
26.7k
    std::vector<uint8_t> ret(getSize);
151
152
26.7k
    if ( getSize > 0 ) {
153
24.0k
        memcpy(ret.data(), data + idx, getSize);
154
24.0k
    }
155
26.7k
    idx += getSize;
156
26.7k
    left -= getSize;
157
158
26.7k
    return ret;
159
27.1k
}
160
#endif
161
162
} /* namespace datasource */
163
} /* namespace fuzzing */