Coverage Report

Created: 2024-11-21 06:35

/src/gfwx-fuzzers/fuzzing-headers/include/fuzzing/datasource/datasource.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef FUZZING_DATASOURCE_DATASOURCE_HPP
2
#define FUZZING_DATASOURCE_DATASOURCE_HPP
3
4
#include <fuzzing/exception.hpp>
5
#include <fuzzing/types.hpp>
6
#include <cstddef>
7
#include <cstdint>
8
#include <cstdlib>
9
#include <cstring>
10
#include <string>
11
#include <vector>
12
13
namespace fuzzing {
14
namespace datasource  {
15
16
class Base
17
{
18
    protected:
19
        virtual std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) = 0;
20
    public:
21
3.25k
        Base(void) = default;
22
3.25k
        virtual ~Base(void) = default;
23
24
        template<class T> T Get(const uint64_t id = 0);
25
        uint16_t GetChoice(const uint64_t id = 0);
26
        std::vector<uint8_t> GetData(const uint64_t id, const size_t min = 0, const size_t max = 0);
27
        template <class T> std::vector<T> GetVector(const uint64_t id = 0);
28
29
        class OutOfData : public fuzzing::exception::FlowException {
30
            public:
31
207
                OutOfData() = default;
32
        };
33
34
        class DeserializationFailure : public fuzzing::exception::FlowException {
35
            public:
36
                DeserializationFailure() = default;
37
        };
38
};
39
40
#ifndef FUZZING_HEADERS_NO_IMPL
41
template<class T> T Base::Get(const uint64_t id)
42
25.4k
{
43
25.4k
    T ret;
44
25.4k
    const auto v = get(sizeof(ret), sizeof(ret), id);
45
25.4k
    memcpy(&ret, v.data(), sizeof(ret));
46
25.4k
    return ret;
47
25.4k
}
unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long)
Line
Count
Source
42
6.16k
{
43
6.16k
    T ret;
44
6.16k
    const auto v = get(sizeof(ret), sizeof(ret), id);
45
6.16k
    memcpy(&ret, v.data(), sizeof(ret));
46
6.16k
    return ret;
47
6.16k
}
unsigned long fuzzing::datasource::Base::Get<unsigned long>(unsigned long)
Line
Count
Source
42
6.22k
{
43
6.22k
    T ret;
44
6.22k
    const auto v = get(sizeof(ret), sizeof(ret), id);
45
6.22k
    memcpy(&ret, v.data(), sizeof(ret));
46
6.22k
    return ret;
47
6.22k
}
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long)
Line
Count
Source
42
13.0k
{
43
13.0k
    T ret;
44
13.0k
    const auto v = get(sizeof(ret), sizeof(ret), id);
45
13.0k
    memcpy(&ret, v.data(), sizeof(ret));
46
13.0k
    return ret;
47
13.0k
}
48
49
template <> bool Base::Get<bool>(const uint64_t id)
50
3.05k
{
51
3.05k
    uint8_t ret;
52
3.05k
    const auto v = get(sizeof(ret), sizeof(ret), id);
53
3.05k
    memcpy(&ret, v.data(), sizeof(ret));
54
3.05k
    return (ret % 2) ? true : false;
55
3.05k
}
56
57
template <> std::string Base::Get<std::string>(const uint64_t id)
58
0
{
59
0
    auto data = GetData(id);
60
0
    return std::string(data.data(), data.data() + data.size());
61
0
}
62
63
template <> std::vector<std::string> Base::Get<std::vector<std::string>>(const uint64_t id)
64
0
{
65
0
    std::vector<std::string> ret;
66
0
    while ( true ) {
67
0
        auto data = GetData(id);
68
0
        ret.push_back( std::string(data.data(), data.data() + data.size()) );
69
0
        if ( Get<bool>(id) == false ) {
70
0
            break;
71
0
        }
72
0
    }
73
0
    return ret;
74
0
}
75
76
uint16_t Base::GetChoice(const uint64_t id)
77
0
{
78
0
    return Get<uint16_t>(id);
79
0
}
80
81
std::vector<uint8_t> Base::GetData(const uint64_t id, const size_t min, const size_t max)
82
3.25k
{
83
3.25k
    return get(min, max, id);
84
3.25k
}
85
86
87
0
template <> types::String<> Base::Get<types::String<>>(const uint64_t id) {
88
0
    const auto data = GetData(id);
89
0
    types::String<> ret(data.data(), data.size());
90
0
    return ret;
91
0
}
92
93
0
template <> types::Data<> Base::Get<types::Data<>>(const uint64_t id) {
94
0
    const auto data = GetData(id);
95
0
    types::Data<> ret(data.data(), data.size());
96
0
    return ret;
97
0
}
98
99
template <class T>
100
std::vector<T> Base::GetVector(const uint64_t id) {
101
    std::vector<T> ret;
102
103
    while ( Get<bool>(id) == true ) {
104
        ret.push_back( Get<T>(id) );
105
    }
106
107
    return ret;
108
}
109
#endif
110
111
class Datasource : public Base
112
{
113
    private:
114
        const uint8_t* data;
115
        const size_t size;
116
        size_t idx;
117
        size_t left;
118
        std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) override;
119
    public:
120
        Datasource(const uint8_t* _data, const size_t _size);
121
};
122
123
#ifndef FUZZING_HEADERS_NO_IMPL
124
Datasource::Datasource(const uint8_t* _data, const size_t _size) :
125
3.25k
    Base(), data(_data), size(_size), idx(0), left(size)
126
3.25k
{
127
3.25k
}
128
129
31.7k
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
130
31.7k
    (void)id;
131
132
31.7k
    uint32_t getSize;
133
31.7k
    if ( left < sizeof(getSize) ) {
134
99
        throw OutOfData();
135
99
    }
136
31.6k
    memcpy(&getSize, data + idx, sizeof(getSize));
137
31.6k
    idx += sizeof(getSize);
138
31.6k
    left -= sizeof(getSize);
139
140
31.6k
    if ( getSize < min ) {
141
1.42k
        getSize = min;
142
1.42k
    }
143
31.6k
    if ( max && getSize > max ) {
144
26.8k
        getSize = max;
145
26.8k
    }
146
147
31.6k
    if ( left < getSize ) {
148
108
        throw OutOfData();
149
108
    }
150
151
31.5k
    std::vector<uint8_t> ret(getSize);
152
153
31.5k
    if ( getSize > 0 ) {
154
31.4k
        memcpy(ret.data(), data + idx, getSize);
155
31.4k
    }
156
31.5k
    idx += getSize;
157
31.5k
    left -= getSize;
158
159
31.5k
    return ret;
160
31.6k
}
161
#endif
162
163
} /* namespace datasource */
164
} /* namespace fuzzing */
165
166
#endif