xref: /aosp_15_r20/external/flac/oss-fuzz/fuzzing/types.hpp (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
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 <cstdint>
27 #include <cstdlib>
28 #include <cstring>
29 #include <fuzzing/memory.hpp>
30 #include <vector>
31 #include <string>
32 
33 namespace fuzzing {
34 namespace types {
35 
36 template <typename CoreType, bool NullTerminated, bool UseMSAN = false>
37 class Container {
38     private:
39         CoreType* InvalidAddress = (CoreType*)0x12;
40 
41         CoreType* _data = InvalidAddress;
42         size_t _size = 0;
43 
44 #ifndef FUZZING_HEADERS_NO_IMPL
copy(const void * data,size_t size)45         void copy(const void* data, size_t size) {
46             if ( size > 0 ) {
47                 std::memcpy(_data, data, size);
48             }
49         }
50 
allocate(size_t size)51         void allocate(size_t size) {
52             if ( size > 0 ) {
53                 _data = static_cast<CoreType*>(malloc(size * sizeof(CoreType)));
54             } else {
55                 _data = InvalidAddress;
56             }
57         };
58 
allocate_and_copy(const void * data,size_t size)59         void allocate_and_copy(const void* data, size_t size) {
60             allocate(size);
61             copy(data, size);
62         }
63 
allocate_plus_1_and_copy(const void * data,size_t size)64         void allocate_plus_1_and_copy(const void* data, size_t size) {
65             allocate(size+1);
66             copy(data, size);
67         }
68 
access_hook(void) const69         void access_hook(void) const {
70             if ( UseMSAN == true ) {
71                 memory::memory_test_msan(_data, _size);
72             }
73         }
74 
free(void)75         void free(void) {
76             access_hook();
77 
78             if ( _data != InvalidAddress ) {
79                 std::free(_data);
80                 _data = InvalidAddress;
81                 _size = 0;
82             }
83         }
84 
85 #endif
86 
87     public:
88 #ifndef FUZZING_HEADERS_NO_IMPL
data(void)89         CoreType* data(void) {
90             access_hook();
91             return _data;
92         }
93 
size(void) const94         size_t size(void) const {
95             access_hook();
96             return _size;
97         }
98 #endif
99 
100         Container(void)
101 #ifndef FUZZING_HEADERS_NO_IMPL
102         = default
103 #endif
104         ;
105 
Container(const void * data,const size_t size)106         Container(const void* data, const size_t size)
107 #ifndef FUZZING_HEADERS_NO_IMPL
108         {
109             if ( NullTerminated == false ) {
110                 allocate_and_copy(data, size);
111             } else {
112                 allocate_plus_1_and_copy(data, size);
113                 _data[size] = 0;
114             }
115 
116             access_hook();
117         }
118 #endif
119         ;
120 
121         template<class T>
Container(const T & t)122         Container(const T& t)
123 #ifndef FUZZING_HEADERS_NO_IMPL
124         {
125             Container(t.data(), t.size());
126         }
127 #endif
128         ;
129 
~Container(void)130         ~Container(void)
131 #ifndef FUZZING_HEADERS_NO_IMPL
132         {
133             this->free();
134         }
135 #endif
136         ;
137 
138 
139 
140         // The copy constructor was not originally explicitly supplied
141         // so it must have been incorrectly just copying the pointers.
Container(const Container & c)142         Container(const Container &c) {
143           InvalidAddress = c.InvalidAddress;
144           allocate_and_copy(c._data, c._size);
145         }
146 
operator =(Container & c)147         Container& operator=(Container &c) {
148           InvalidAddress = c.InvalidAddress;
149           allocate_and_copy(c._data, c._size);
150         }
151 
152 };
153 
154 template <bool UseMSAN = false> using String = Container<char, true, UseMSAN>;
155 template <bool UseMSAN = false> using Data = Container<uint8_t, false, UseMSAN>;
156 
157 } /* namespace types */
158 } /* namespace fuzzing */
159