summaryrefslogtreecommitdiff
path: root/oss-fuzz/fuzzing/types.hpp
blob: f2b56fc30d825f29d42af07622a34c937230885e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#pragma once

#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <fuzzing/memory.hpp>
#include <vector>
#include <string>

namespace fuzzing {
namespace types {

template <typename CoreType, bool NullTerminated, bool UseMSAN = false>
class Container {
    private:
        CoreType* InvalidAddress = (CoreType*)0x12;

        CoreType* _data = InvalidAddress;
        size_t _size = 0;

#ifndef FUZZING_HEADERS_NO_IMPL
        void copy(const void* data, size_t size) {
            if ( size > 0 ) {
                std::memcpy(_data, data, size);
            }
        }

        void allocate(size_t size) {
            if ( size > 0 ) {
                _data = static_cast<CoreType*>(malloc(size * sizeof(CoreType)));
            } else {
                _data = InvalidAddress;
            }
        };

        void allocate_and_copy(const void* data, size_t size) {
            allocate(size);
            copy(data, size);
        }

        void allocate_plus_1_and_copy(const void* data, size_t size) {
            allocate(size+1);
            copy(data, size);
        }

        void access_hook(void) const {
            if ( UseMSAN == true ) {
                memory::memory_test_msan(_data, _size);
            }
        }

        void free(void) {
            access_hook();

            if ( _data != InvalidAddress ) {
                std::free(_data);
                _data = InvalidAddress;
                _size = 0;
            }
        }

#endif

    public:
#ifndef FUZZING_HEADERS_NO_IMPL
        CoreType* data(void) {
            access_hook();
            return _data;
        }

        size_t size(void) const {
            access_hook();
            return _size;
        }
#endif

        Container(void)
#ifndef FUZZING_HEADERS_NO_IMPL
        = default
#endif
        ;

        Container(const void* data, const size_t size)
#ifndef FUZZING_HEADERS_NO_IMPL
        {
            if ( NullTerminated == false ) {
                allocate_and_copy(data, size);
            } else {
                allocate_plus_1_and_copy(data, size);
                _data[size] = 0;
            }

            access_hook();
        }
#endif
        ;

        template<class T>
        Container(const T& t)
#ifndef FUZZING_HEADERS_NO_IMPL
        {
            Container(t.data(), t.size());
        }
#endif
        ;

        ~Container(void)
#ifndef FUZZING_HEADERS_NO_IMPL
        {
            this->free();
        }
#endif
        ;



        // The copy constructor was not originally explicitly supplied
        // so it must have been incorrectly just copying the pointers.
        Container(const Container &c) {
          InvalidAddress = c.InvalidAddress;
          allocate_and_copy(c._data, c._size);
        }

        Container& operator=(Container &c) {
          InvalidAddress = c.InvalidAddress;
          allocate_and_copy(c._data, c._size);
        }

};

template <bool UseMSAN = false> using String = Container<char, true, UseMSAN>;
template <bool UseMSAN = false> using Data = Container<uint8_t, false, UseMSAN>;

} /* namespace types */
} /* namespace fuzzing */