From 5597fc56d3153457952edd326869aeb5a85e169b 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 9e6795da..e74cfbd5 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;