Coverage Report

Created: 2025-12-14 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flac/oss-fuzz/fuzzing/datasource/datasource.hpp
Line
Count
Source
1
/* Copyright 2019 Guido Vranken
2
 *
3
 * Permission is hereby granted, free of charge, to any person obtaining
4
 * a copy of this software and associated documentation files (the
5
 * "Software"), to deal in the Software without restriction, including
6
 * without limitation the rights to use, copy, modify, merge, publish,
7
 * distribute, sublicense, and/or sell copies of the Software, and to
8
 * permit persons to whom the Software is furnished to do so, subject
9
 * to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be
12
 * included in all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
22
 */
23
24
#pragma once
25
26
#include <fuzzing/exception.hpp>
27
#include <fuzzing/types.hpp>
28
#include <cstddef>
29
#include <cstdint>
30
#include <cstdlib>
31
#include <cstring>
32
#include <string>
33
#include <vector>
34
35
namespace fuzzing {
36
namespace datasource  {
37
38
class Base
39
{
40
    protected:
41
        virtual std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) = 0;
42
    public:
43
8.88k
        Base(void) = default;
44
8.88k
        virtual ~Base(void) = default;
45
46
        template<class T> T Get(const uint64_t id = 0);
47
        uint16_t GetChoice(const uint64_t id = 0);
48
        std::vector<uint8_t> GetData(const uint64_t id, const size_t min = 0, const size_t max = 0);
49
        template <class T> std::vector<T> GetVector(const uint64_t id = 0);
50
51
        class OutOfData : public fuzzing::exception::FlowException {
52
            public:
53
138k
                OutOfData() = default;
54
        };
55
56
        class DeserializationFailure : public fuzzing::exception::FlowException {
57
            public:
58
                DeserializationFailure() = default;
59
        };
60
};
61
62
#ifndef FUZZING_HEADERS_NO_IMPL
63
template<class T> T Base::Get(const uint64_t id)
64
253k
{
65
253k
    T ret;
66
253k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
253k
    memcpy(&ret, v.data(), sizeof(ret));
68
253k
    return ret;
69
253k
}
Unexecuted instantiation: unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long)
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long)
Line
Count
Source
64
252k
{
65
252k
    T ret;
66
252k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
252k
    memcpy(&ret, v.data(), sizeof(ret));
68
252k
    return ret;
69
252k
}
long fuzzing::datasource::Base::Get<long>(unsigned long)
Line
Count
Source
64
30
{
65
30
    T ret;
66
30
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
30
    memcpy(&ret, v.data(), sizeof(ret));
68
30
    return ret;
69
30
}
unsigned long fuzzing::datasource::Base::Get<unsigned long>(unsigned long)
Line
Count
Source
64
724
{
65
724
    T ret;
66
724
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
724
    memcpy(&ret, v.data(), sizeof(ret));
68
724
    return ret;
69
724
}
70
71
template <> bool Base::Get<bool>(const uint64_t id)
72
497k
{
73
497k
    uint8_t ret;
74
497k
    const auto v = get(sizeof(ret), sizeof(ret), id);
75
497k
    memcpy(&ret, v.data(), sizeof(ret));
76
497k
    return (ret % 2) ? true : false;
77
497k
}
78
79
template <> std::string Base::Get<std::string>(const uint64_t id)
80
0
{
81
0
    auto data = GetData(id);
82
0
    return std::string(data.data(), data.data() + data.size());
83
0
}
84
85
template <> std::vector<std::string> Base::Get<std::vector<std::string>>(const uint64_t id)
86
0
{
87
0
    std::vector<std::string> ret;
88
0
    while ( true ) {
89
0
        auto data = GetData(id);
90
0
        ret.push_back( std::string(data.data(), data.data() + data.size()) );
91
0
        if ( Get<bool>(id) == false ) {
92
0
            break;
93
0
        }
94
0
    }
95
0
    return ret;
96
0
}
97
98
uint16_t Base::GetChoice(const uint64_t id)
99
0
{
100
0
    return Get<uint16_t>(id);
101
0
}
102
103
std::vector<uint8_t> Base::GetData(const uint64_t id, const size_t min, const size_t max)
104
183k
{
105
183k
    return get(min, max, id);
106
183k
}
107
108
109
0
template <> types::String<> Base::Get<types::String<>>(const uint64_t id) {
110
0
    const auto data = GetData(id);
111
0
    types::String<> ret(data.data(), data.size());
112
0
    return ret;
113
0
}
114
115
0
template <> types::Data<> Base::Get<types::Data<>>(const uint64_t id) {
116
0
    const auto data = GetData(id);
117
0
    types::Data<> ret(data.data(), data.size());
118
0
    return ret;
119
0
}
120
121
template <class T>
122
std::vector<T> Base::GetVector(const uint64_t id) {
123
    std::vector<T> ret;
124
125
    while ( Get<bool>(id) == true ) {
126
        ret.push_back( Get<T>(id) );
127
    }
128
129
    return ret;
130
}
131
#endif
132
133
class Datasource : public Base
134
{
135
    private:
136
        const uint8_t* data;
137
        const size_t size;
138
        size_t idx;
139
        size_t left;
140
        std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) override;
141
142
    // Make copy constructor and assignment operator private.
143
0
        Datasource(const Datasource &) : data(0), size(0), idx(0), left(0) {}
144
0
        Datasource& operator=(const Datasource &) { return *this; }
145
    public:
146
        Datasource(const uint8_t* _data, const size_t _size);
147
};
148
149
#ifndef FUZZING_HEADERS_NO_IMPL
150
Datasource::Datasource(const uint8_t* _data, const size_t _size) :
151
8.88k
    Base(), data(_data), size(_size), idx(0), left(size)
152
8.88k
{
153
8.88k
}
154
155
933k
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
156
933k
    (void)id;
157
158
933k
    uint32_t getSize;
159
933k
    if ( left < sizeof(getSize) ) {
160
89.4k
        throw OutOfData();
161
89.4k
    }
162
844k
    memcpy(&getSize, data + idx, sizeof(getSize));
163
844k
    idx += sizeof(getSize);
164
844k
    left -= sizeof(getSize);
165
166
844k
    if ( getSize < min ) {
167
6.72k
        getSize = min;
168
6.72k
    }
169
844k
    if ( max && getSize > max ) {
170
660k
        getSize = max;
171
660k
    }
172
173
844k
    if ( left < getSize ) {
174
48.6k
        throw OutOfData();
175
48.6k
    }
176
177
795k
    std::vector<uint8_t> ret(getSize);
178
179
795k
    if ( getSize > 0 ) {
180
742k
        memcpy(ret.data(), data + idx, getSize);
181
742k
    }
182
795k
    idx += getSize;
183
795k
    left -= getSize;
184
185
795k
    return ret;
186
844k
}
187
#endif
188
189
} /* namespace datasource */
190
} /* namespace fuzzing */