From afb40f1d8df313574dca025f9bd4142881ff264b Mon Sep 17 00:00:00 2001 From: peace-maker Date: Thu, 30 Apr 2020 18:59:54 +0200 Subject: [PATCH] Fix crash when ArrayList runs out of memory (#1235) The allocation size was still updated to the bigger size even if memory allocation failed. Trying to write to the supposedly available new space would overflow the heap and crash. Fixes #1233 --- core/logic/CellArray.h | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/core/logic/CellArray.h b/core/logic/CellArray.h index 9e6795daa..e74cfbd51 100644 --- a/core/logic/CellArray.h +++ b/core/logic/CellArray.h @@ -35,6 +35,7 @@ #include #include #include +#include extern HandleType_t htCellArray; @@ -214,30 +215,34 @@ private: { return true; } + size_t newAllocSize = m_AllocSize; /* Set a base allocation size of 8 items */ - if (!m_AllocSize) + if (!newAllocSize) { - m_AllocSize = 8; + newAllocSize = 8; + } + if (!ke::IsUintPtrAddSafe(m_Size, count)) + { + return false; } /* If it's not enough, keep doubling */ - while (m_Size + count > m_AllocSize) + while (m_Size + count > newAllocSize) { - m_AllocSize *= 2; - } - /* finally, allocate the new block */ - if (m_Data) - { - cell_t *data = static_cast(realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize)); - if (!data) // allocation failure + if (!ke::IsUintPtrMultiplySafe(newAllocSize, 2)) { return false; } - - m_Data = data; - } else { - m_Data = static_cast(malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize)); + newAllocSize *= 2; } - return (m_Data != nullptr); + /* finally, allocate the new block */ + cell_t *data = static_cast(realloc(m_Data, sizeof(cell_t) * m_BlockSize * newAllocSize)); + /* Update state if allocation was successful */ + if (data) + { + m_AllocSize = newAllocSize; + m_Data = data; + } + return (data != nullptr); } private: cell_t *m_Data;