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