/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 */ |