Add minimum offset checking to FS Ptr

This commit is contained in:
Gary Talent 2018-03-08 00:32:25 -06:00
parent b77a41abd2
commit af4ab51df4
3 changed files with 25 additions and 24 deletions

View File

@ -22,11 +22,11 @@ class __attribute__((packed)) NodeBuffer {
ox::LittleEndian<size_t> firstItem = 0; ox::LittleEndian<size_t> firstItem = 0;
}; };
struct ItemPtr: public ox::fs::Ptr<Item, size_t> { struct ItemPtr: public ox::fs::Ptr<Item, size_t, sizeof(Header)> {
inline ItemPtr() = default; inline ItemPtr() = default;
inline ItemPtr(void *dataStart, size_t dataSize, size_t itemOffset, size_t size): inline ItemPtr(void *dataStart, size_t dataSize, size_t itemOffset, size_t size):
Ptr<Item, size_t>(dataStart, dataSize, itemOffset, size) { Ptr<Item, size_t, sizeof(Header)>(dataStart, dataSize, itemOffset, size) {
} }
inline ItemPtr(void *dataStart, size_t dataSize, size_t itemOffset) { inline ItemPtr(void *dataStart, size_t dataSize, size_t itemOffset) {

View File

@ -13,7 +13,7 @@
namespace ox { namespace ox {
namespace fs { namespace fs {
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset = 1>
class Ptr { class Ptr {
private: private:
@ -47,62 +47,63 @@ class Ptr {
}; };
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t>::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) { inline Ptr<T, size_t, minOffset>::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) {
init(dataStart, dataSize, itemStart, itemSize); init(dataStart, dataSize, itemStart, itemSize);
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline bool Ptr<T, size_t>::valid() const { inline bool Ptr<T, size_t, minOffset>::valid() const {
return m_dataStart and m_itemOffset; return m_dataStart and m_itemOffset;
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline size_t Ptr<T, size_t>::size() const { inline size_t Ptr<T, size_t, minOffset>::size() const {
return m_itemSize; return m_itemSize;
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline size_t Ptr<T, size_t>::offset() const { inline size_t Ptr<T, size_t, minOffset>::offset() const {
return m_itemOffset; return m_itemOffset;
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline size_t Ptr<T, size_t>::end() { inline size_t Ptr<T, size_t, minOffset>::end() {
return m_itemOffset + m_itemSize; return m_itemOffset + m_itemSize;
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline T *Ptr<T, size_t>::operator->() const { inline T *Ptr<T, size_t, minOffset>::operator->() const {
ox_assert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())"); ox_assert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t>::operator T*() const { inline Ptr<T, size_t, minOffset>::operator T*() const {
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t>::operator size_t() const { inline Ptr<T, size_t, minOffset>::operator size_t() const {
if (valid()) { if (valid()) {
return m_itemOffset; return m_itemOffset;
} }
return 0; return 0;
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
inline T &Ptr<T, size_t>::operator*() const { inline T &Ptr<T, size_t, minOffset>::operator*() const {
ox_assert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())"); ox_assert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
return *static_cast<T>(this); return *static_cast<T>(this);
} }
template<typename T, typename size_t> template<typename T, typename size_t, size_t minOffset>
void Ptr<T, size_t>::init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) { void Ptr<T, size_t, minOffset>::init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) {
// do some sanity checks before assuming this is valid // do some sanity checks before assuming this is valid
m_dataStart = static_cast<uint8_t*>(dataStart); m_dataStart = static_cast<uint8_t*>(dataStart);
if (itemSize >= sizeof(T) and if (itemSize >= sizeof(T) and
dataStart and dataStart and
itemStart >= minOffset and
itemStart + itemSize <= dataSize) { itemStart + itemSize <= dataSize) {
m_itemOffset = itemStart; m_itemOffset = itemStart;
m_itemSize = itemSize; m_itemSize = itemSize;