/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 | 2.98k | Base(void) = default; |
21 | 2.98k | 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 | 5.21k | 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 | 33.6k | { |
42 | 33.6k | T ret; |
43 | 33.6k | const auto v = get(sizeof(ret), sizeof(ret), id); |
44 | 33.6k | memcpy(&ret, v.data(), sizeof(ret)); |
45 | 33.6k | return ret; |
46 | 33.6k | } unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long) Line | Count | Source | 41 | 9.83k | { | 42 | 9.83k | T ret; | 43 | 9.83k | const auto v = get(sizeof(ret), sizeof(ret), id); | 44 | 9.83k | memcpy(&ret, v.data(), sizeof(ret)); | 45 | 9.83k | return ret; | 46 | 9.83k | } |
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long) Line | Count | Source | 41 | 16.2k | { | 42 | 16.2k | T ret; | 43 | 16.2k | const auto v = get(sizeof(ret), sizeof(ret), id); | 44 | 16.2k | memcpy(&ret, v.data(), sizeof(ret)); | 45 | 16.2k | return ret; | 46 | 16.2k | } |
unsigned int fuzzing::datasource::Base::Get<unsigned int>(unsigned long) Line | Count | Source | 41 | 7.53k | { | 42 | 7.53k | T ret; | 43 | 7.53k | const auto v = get(sizeof(ret), sizeof(ret), id); | 44 | 7.53k | memcpy(&ret, v.data(), sizeof(ret)); | 45 | 7.53k | return ret; | 46 | 7.53k | } |
|
47 | | |
48 | | template <> bool Base::Get<bool>(const uint64_t id) |
49 | 17.0k | { |
50 | 17.0k | uint8_t ret; |
51 | 17.0k | const auto v = get(sizeof(ret), sizeof(ret), id); |
52 | 17.0k | memcpy(&ret, v.data(), sizeof(ret)); |
53 | 17.0k | return (ret % 2) ? true : false; |
54 | 17.0k | } |
55 | | |
56 | | template <> std::string Base::Get<std::string>(const uint64_t id) |
57 | 8.16k | { |
58 | 8.16k | auto data = GetData(id); |
59 | 8.16k | return std::string(data.data(), data.data() + data.size()); |
60 | 8.16k | } |
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 | 29.2k | { |
82 | 29.2k | return get(min, max, id); |
83 | 29.2k | } |
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 | 2.98k | Base(), data(_data), size(_size), idx(0), left(size) |
125 | 2.98k | { |
126 | 2.98k | } |
127 | | |
128 | 79.9k | std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) { |
129 | 79.9k | (void)id; |
130 | | |
131 | 79.9k | uint32_t getSize; |
132 | 79.9k | if ( left < sizeof(getSize) ) { |
133 | 3.30k | throw OutOfData(); |
134 | 3.30k | } |
135 | 76.6k | memcpy(&getSize, data + idx, sizeof(getSize)); |
136 | 76.6k | idx += sizeof(getSize); |
137 | 76.6k | left -= sizeof(getSize); |
138 | | |
139 | 76.6k | if ( getSize < min ) { |
140 | 6.88k | getSize = min; |
141 | 6.88k | } |
142 | 76.6k | if ( max && getSize > max ) { |
143 | 40.8k | getSize = max; |
144 | 40.8k | } |
145 | | |
146 | 76.6k | if ( left < getSize ) { |
147 | 1.91k | throw OutOfData(); |
148 | 1.91k | } |
149 | | |
150 | 74.7k | std::vector<uint8_t> ret(getSize); |
151 | | |
152 | 74.7k | if ( getSize > 0 ) { |
153 | 65.8k | memcpy(ret.data(), data + idx, getSize); |
154 | 65.8k | } |
155 | 74.7k | idx += getSize; |
156 | 74.7k | left -= getSize; |
157 | | |
158 | 74.7k | return ret; |
159 | 76.6k | } |
160 | | #endif |
161 | | |
162 | | } /* namespace datasource */ |
163 | | } /* namespace fuzzing */ |