1 #pragma once 2 3 #include <cstdint> 4 #include <cstdlib> 5 #include <cstring> 6 #include <fuzzing/memory.hpp> 7 #include <vector> 8 #include <string> 9 10 namespace fuzzing { 11 namespace types { 12 13 template <typename CoreType, bool NullTerminated, bool UseMSAN = false> 14 class Container { 15 private: 16 CoreType* InvalidAddress = (CoreType*)0x12; 17 18 CoreType* _data = InvalidAddress; 19 size_t _size = 0; 20 21 #ifndef FUZZING_HEADERS_NO_IMPL copy(const void * data,size_t size)22 void copy(const void* data, size_t size) { 23 if ( size > 0 ) { 24 std::memcpy(_data, data, size); 25 } 26 } 27 allocate(size_t size)28 void allocate(size_t size) { 29 if ( size > 0 ) { 30 _data = static_cast<CoreType*>(malloc(size * sizeof(CoreType))); 31 } else { 32 _data = InvalidAddress; 33 } 34 }; 35 allocate_and_copy(const void * data,size_t size)36 void allocate_and_copy(const void* data, size_t size) { 37 allocate(size); 38 copy(data, size); 39 } 40 allocate_plus_1_and_copy(const void * data,size_t size)41 void allocate_plus_1_and_copy(const void* data, size_t size) { 42 allocate(size+1); 43 copy(data, size); 44 } 45 access_hook(void) const46 void access_hook(void) const { 47 if ( UseMSAN == true ) { 48 memory::memory_test_msan(_data, _size); 49 } 50 } 51 free(void)52 void free(void) { 53 access_hook(); 54 55 if ( _data != InvalidAddress ) { 56 std::free(_data); 57 _data = InvalidAddress; 58 _size = 0; 59 } 60 } 61 62 #endif 63 64 public: 65 #ifndef FUZZING_HEADERS_NO_IMPL data(void)66 CoreType* data(void) { 67 access_hook(); 68 return _data; 69 } 70 size(void) const71 size_t size(void) const { 72 access_hook(); 73 return _size; 74 } 75 #endif 76 77 Container(void) 78 #ifndef FUZZING_HEADERS_NO_IMPL 79 = default 80 #endif 81 ; 82 Container(const void * data,const size_t size)83 Container(const void* data, const size_t size) 84 #ifndef FUZZING_HEADERS_NO_IMPL 85 { 86 if ( NullTerminated == false ) { 87 allocate_and_copy(data, size); 88 } else { 89 allocate_plus_1_and_copy(data, size); 90 _data[size] = 0; 91 } 92 93 access_hook(); 94 } 95 #endif 96 ; 97 98 template<class T> Container(const T & t)99 Container(const T& t) 100 #ifndef FUZZING_HEADERS_NO_IMPL 101 { 102 Container(t.data(), t.size()); 103 } 104 #endif 105 ; 106 ~Container(void)107 ~Container(void) 108 #ifndef FUZZING_HEADERS_NO_IMPL 109 { 110 this->free(); 111 } 112 #endif 113 ; 114 115 116 117 // The copy constructor was not originally explicitly supplied 118 // so it must have been incorrectly just copying the pointers. Container(const Container & c)119 Container(const Container &c) { 120 InvalidAddress = c.InvalidAddress; 121 allocate_and_copy(c._data, c._size); 122 } 123 operator =(Container & c)124 Container& operator=(Container &c) { 125 InvalidAddress = c.InvalidAddress; 126 allocate_and_copy(c._data, c._size); 127 } 128 129 }; 130 131 template <bool UseMSAN = false> using String = Container<char, true, UseMSAN>; 132 template <bool UseMSAN = false> using Data = Container<uint8_t, false, UseMSAN>; 133 134 } /* namespace types */ 135 } /* namespace fuzzing */ 136