/* Copyright 2019 Guido Vranken * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject * to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #pragma once #include #include #include #include #include #include namespace fuzzing { namespace types { template 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(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 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 using String = Container; template using Data = Container; } /* namespace types */ } /* namespace fuzzing */