From 970600081c6ca0068e28e3e811a2c50426159ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Mon, 13 Jan 2025 22:02:49 +0100 Subject: [PATCH] Fix crash when loading very long localization lines The client previously crashed when loading a localization file with a replacement line (plus zero terminator) longer than the size of a `CHeap` chunk (65600 bytes) due to the line data being written outside the heap chunk. This is fixed by allowing `CHeap` to allocate chunks as large as necessary to contain at least one item. As an alternative the `CHeap` functions could be changed to return `nullptr` if the wanted allocation is too large, which would have to be handled explicitly when loading localization files. --- src/engine/shared/memheap.cpp | 13 ++++++++----- src/engine/shared/memheap.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/engine/shared/memheap.cpp b/src/engine/shared/memheap.cpp index 311a6ddb432..b80546b1ade 100644 --- a/src/engine/shared/memheap.cpp +++ b/src/engine/shared/memheap.cpp @@ -1,21 +1,24 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include "memheap.h" + +#include #include + #include #include // allocates a new chunk to be used -void CHeap::NewChunk() +void CHeap::NewChunk(size_t ChunkSize) { // the chunk structure is located in the beginning of the chunk // init it and return the chunk - CChunk *pChunk = static_cast(malloc(sizeof(CChunk) + CHUNK_SIZE)); + CChunk *pChunk = static_cast(malloc(sizeof(CChunk) + ChunkSize)); if(!pChunk) return; pChunk->m_pMemory = static_cast(static_cast(pChunk + 1)); pChunk->m_pCurrent = pChunk->m_pMemory; - pChunk->m_pEnd = pChunk->m_pMemory + CHUNK_SIZE; + pChunk->m_pEnd = pChunk->m_pMemory + ChunkSize; pChunk->m_pNext = nullptr; pChunk->m_pNext = m_pCurrent; @@ -54,7 +57,7 @@ CHeap::~CHeap() void CHeap::Reset() { Clear(); - NewChunk(); + NewChunk(CHUNK_SIZE); } // destroys the heap @@ -76,7 +79,7 @@ void *CHeap::Allocate(unsigned Size, unsigned Alignment) if(!pMem) { // allocate new chunk and add it to the heap - NewChunk(); + NewChunk(maximum(CHUNK_SIZE, Size + Alignment)); // try to allocate again pMem = AllocateFromChunk(Size, Alignment); diff --git a/src/engine/shared/memheap.h b/src/engine/shared/memheap.h index acabfa62336..4565ce6db05 100644 --- a/src/engine/shared/memheap.h +++ b/src/engine/shared/memheap.h @@ -26,7 +26,7 @@ class CHeap CChunk *m_pCurrent; void Clear(); - void NewChunk(); + void NewChunk(size_t ChunkSize); void *AllocateFromChunk(unsigned int Size, unsigned Alignment); public: