Coverage Report

Created: 2025-10-12 06:46

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.00k
        Base(void) = default;
44
8.00k
        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
8.71k
                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
95.0k
{
65
95.0k
    T ret;
66
95.0k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
95.0k
    memcpy(&ret, v.data(), sizeof(ret));
68
95.0k
    return ret;
69
95.0k
}
unsigned short fuzzing::datasource::Base::Get<unsigned short>(unsigned long)
Line
Count
Source
64
7.92k
{
65
7.92k
    T ret;
66
7.92k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
7.92k
    memcpy(&ret, v.data(), sizeof(ret));
68
7.92k
    return ret;
69
7.92k
}
unsigned char fuzzing::datasource::Base::Get<unsigned char>(unsigned long)
Line
Count
Source
64
31.8k
{
65
31.8k
    T ret;
66
31.8k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
31.8k
    memcpy(&ret, v.data(), sizeof(ret));
68
31.8k
    return ret;
69
31.8k
}
long fuzzing::datasource::Base::Get<long>(unsigned long)
Line
Count
Source
64
7.95k
{
65
7.95k
    T ret;
66
7.95k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
7.95k
    memcpy(&ret, v.data(), sizeof(ret));
68
7.95k
    return ret;
69
7.95k
}
unsigned int fuzzing::datasource::Base::Get<unsigned int>(unsigned long)
Line
Count
Source
64
39.4k
{
65
39.4k
    T ret;
66
39.4k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
39.4k
    memcpy(&ret, v.data(), sizeof(ret));
68
39.4k
    return ret;
69
39.4k
}
unsigned long fuzzing::datasource::Base::Get<unsigned long>(unsigned long)
Line
Count
Source
64
7.92k
{
65
7.92k
    T ret;
66
7.92k
    const auto v = get(sizeof(ret), sizeof(ret), id);
67
7.92k
    memcpy(&ret, v.data(), sizeof(ret));
68
7.92k
    return ret;
69
7.92k
}
70
71
template <> bool Base::Get<bool>(const uint64_t id)
72
63.1k
{
73
63.1k
    uint8_t ret;
74
63.1k
    const auto v = get(sizeof(ret), sizeof(ret), id);
75
63.1k
    memcpy(&ret, v.data(), sizeof(ret));
76
63.1k
    return (ret % 2) ? true : false;
77
63.1k
}
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
83.3k
{
105
83.3k
    return get(min, max, id);
106
83.3k
}
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.00k
    Base(), data(_data), size(_size), idx(0), left(size)
152
8.00k
{
153
8.00k
}
154
155
241k
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
156
241k
    (void)id;
157
158
241k
    uint32_t getSize;
159
241k
    if ( left < sizeof(getSize) ) {
160
7.41k
        throw OutOfData();
161
7.41k
    }
162
234k
    memcpy(&getSize, data + idx, sizeof(getSize));
163
234k
    idx += sizeof(getSize);
164
234k
    left -= sizeof(getSize);
165
166
234k
    if ( getSize < min ) {
167
11.8k
        getSize = min;
168
11.8k
    }
169
234k
    if ( max && getSize > max ) {
170
144k
        getSize = max;
171
144k
    }
172
173
234k
    if ( left < getSize ) {
174
1.30k
        throw OutOfData();
175
1.30k
    }
176
177
232k
    std::vector<uint8_t> ret(getSize);
178
179
232k
    if ( getSize > 0 ) {
180
171k
        memcpy(ret.data(), data + idx, getSize);
181
171k
    }
182
232k
    idx += getSize;
183
232k
    left -= getSize;
184
185
232k
    return ret;
186
234k
}
187
#endif
188
189
} /* namespace datasource */
190
} /* namespace fuzzing */