From 8f9a0706bfb4088a50a46915a32e3ff2957de6ff Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Wed, 14 Feb 2007 11:03:03 +0000 Subject: [PATCH] improved data pack type checking added readmemory member --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40494 --- core/CDataPack.cpp | 76 +++++++++++++++++++++++++++++++++++------- core/CDataPack.h | 1 + core/smn_datapacks.cpp | 4 +-- public/IDataPack.h | 8 +++++ 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/core/CDataPack.cpp b/core/CDataPack.cpp index 09e932e4..576e808c 100644 --- a/core/CDataPack.cpp +++ b/core/CDataPack.cpp @@ -2,7 +2,7 @@ #include #include "CDataPack.h" -#define DATAPACK_INITIAL_SIZE 512 +#define DATAPACK_INITIAL_SIZE 4//512 CDataPack::CDataPack() { @@ -45,36 +45,47 @@ void CDataPack::ResetSize() size_t CDataPack::CreateMemory(size_t size, void **addr) { + CheckSize(sizeof(size_t) + size); size_t pos = m_curptr - m_pBase; - m_pBase = (char *)realloc(m_pBase, size); - m_curptr = m_pBase + pos; - m_capacity = size; + *(size_t *)m_curptr = size; + m_curptr += sizeof(size_t); if (addr) { - *addr = m_pBase; + *addr = m_curptr; } + m_curptr += size; + m_size += sizeof(size_t) + size; + return pos; } void CDataPack::PackCell(cell_t cell) { - CheckSize(sizeof(cell_t)); + CheckSize(sizeof(size_t) + sizeof(cell_t)); + + *(size_t *)m_curptr = sizeof(cell_t); + m_curptr += sizeof(size_t); *(cell_t *)m_curptr = cell; m_curptr += sizeof(cell_t); - m_size += sizeof(cell_t); + + m_size += sizeof(size_t) + sizeof(cell_t); } void CDataPack::PackFloat(float val) { - CheckSize(sizeof(float)); + CheckSize(sizeof(size_t) + sizeof(float)); + + *(size_t *)m_curptr = sizeof(float); + m_curptr += sizeof(size_t); *(float *)m_curptr = val; m_curptr += sizeof(float); - m_size += sizeof(float); + + m_size += sizeof(size_t) + sizeof(float); } void CDataPack::PackString(const char *string) @@ -118,10 +129,17 @@ bool CDataPack::SetPosition(size_t pos) const cell_t CDataPack::ReadCell() const { - if (!IsReadable(sizeof(cell_t))) + if (!IsReadable(sizeof(size_t) + sizeof(cell_t))) { return 0; } + if (*reinterpret_cast(m_curptr) != sizeof(cell_t)) + { + return 0; + } + + m_curptr += sizeof(size_t); + cell_t val = *reinterpret_cast(m_curptr); m_curptr += sizeof(cell_t); return val; @@ -129,10 +147,17 @@ cell_t CDataPack::ReadCell() const float CDataPack::ReadFloat() const { - if (!IsReadable(sizeof(float))) + if (!IsReadable(sizeof(size_t) + sizeof(float))) { return 0; } + if (*reinterpret_cast(m_curptr) != sizeof(float)) + { + return 0; + } + + m_curptr += sizeof(size_t); + float val = *reinterpret_cast(m_curptr); m_curptr += sizeof(float); return val; @@ -147,7 +172,7 @@ const char *CDataPack::ReadString(size_t *len) const { if (!IsReadable(sizeof(size_t))) { - return 0; + return NULL; } size_t real_len = *(size_t *)m_curptr; @@ -174,3 +199,30 @@ void *CDataPack::GetMemory() const { return m_curptr; } + +void *CDataPack::ReadMemory(size_t *size) const +{ + if (!IsReadable(sizeof(size_t))) + { + return NULL; + } + + size_t bytecount = *(size_t *)m_curptr; + m_curptr += sizeof(size_t); + + if (!IsReadable(bytecount)) + { + return NULL; + } + + void *ptr = m_curptr; + + if (size) + { + *size = bytecount; + } + + m_curptr += bytecount; + + return ptr; +} diff --git a/core/CDataPack.h b/core/CDataPack.h index cb514306..5e86c86b 100644 --- a/core/CDataPack.h +++ b/core/CDataPack.h @@ -33,6 +33,7 @@ public: //IDataReader bool IsReadable(size_t bytes) const; const char *ReadString(size_t *len) const; void *GetMemory() const; + void *ReadMemory(size_t *size) const; public: //IDataPack void ResetSize(); void PackCell(cell_t cell); diff --git a/core/smn_datapacks.cpp b/core/smn_datapacks.cpp index 573715c1..ad5d91ba 100644 --- a/core/smn_datapacks.cpp +++ b/core/smn_datapacks.cpp @@ -123,7 +123,7 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr); } - if (!pDataPack->IsReadable(sizeof(cell_t))) + if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(cell_t))) { return pContext->ThrowNativeError("DataPack operation is out of bounds."); } @@ -147,7 +147,7 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr); } - if (!pDataPack->IsReadable(sizeof(float))) + if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(float))) { return pContext->ThrowNativeError("DataPack operation is out of bounds."); } diff --git a/public/IDataPack.h b/public/IDataPack.h index d5e3fc89..6874428b 100644 --- a/public/IDataPack.h +++ b/public/IDataPack.h @@ -92,6 +92,14 @@ namespace SourceMod * @return Pointer to the memory. */ virtual void *GetMemory() const =0; + + /** + * @brief Reads the current position as a generic data type. + * + * @param size Optional pointer to store the size of the data type. + * @return Pointer to the data, or NULL if out of bounds. + */ + virtual void *ReadMemory(size_t *size) const =0; }; /**