From b1237df06ac42db8beae5314dd6e6ae2ef3ef5e3 Mon Sep 17 00:00:00 2001 From: xomx Date: Mon, 25 Nov 2024 04:12:15 +0100 Subject: [PATCH] Fix a possible buffer overflow issue Fix possible DockingManager::FindEmptyContainer() buffer overflow. Fix #15850, close #15851 --- .../WinControls/DockingWnd/DockingManager.cpp | 75 +++++++++++-------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp b/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp index 392ab6454..1eb7a7188 100644 --- a/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp +++ b/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp @@ -951,43 +951,54 @@ int DockingManager::GetContainer(DockingCont* pCont) int DockingManager::FindEmptyContainer() { - int iRetCont = -1; - BOOL* pPrevDockList = (BOOL*) new BOOL[_vContainer.size()+1]; - BOOL* pArrayPos = &pPrevDockList[1]; + int iRetCont = -1; + const size_t dockingContVectorSize = _vContainer.size(); + const size_t prevDockListBufSize = dockingContVectorSize + 1; + BOOL* pPrevDockList = new BOOL[prevDockListBufSize]; + BOOL* pArrayPos = &pPrevDockList[1]; // make a room for the possible iPrevCont==-1 later - // delete all entries - for (size_t iCont = 0, len = _vContainer.size()+1; iCont < len; ++iCont) - { - pPrevDockList[iCont] = FALSE; - } + // reset all entries + for (size_t iCont = 0, len = prevDockListBufSize; iCont < len; ++iCont) + { + pPrevDockList[iCont] = FALSE; + } - // search for used floated containers - for (size_t iCont = 0; iCont < DOCKCONT_MAX; ++iCont) - { - vector vTbData = _vContainer[iCont]->getDataOfAllTb(); + // search for used floating containers + for (size_t iCont = 0; iCont < DOCKCONT_MAX; ++iCont) + { + vector vTbData = _vContainer[iCont]->getDataOfAllTb(); - for (size_t iTb = 0, len = vTbData.size(); iTb < len; ++iTb) - { - pArrayPos[vTbData[iTb]->iPrevCont] = TRUE; - } - } + for (size_t iTb = 0, len = vTbData.size(); iTb < len; ++iTb) + { + if ((vTbData[iTb]->iPrevCont < static_cast(dockingContVectorSize)) && (vTbData[iTb]->iPrevCont >= -1)) + { + pArrayPos[vTbData[iTb]->iPrevCont] = TRUE; + } + else + { + // ? invalid config.xml input data + assert((vTbData[iTb]->iPrevCont < static_cast(dockingContVectorSize)) && (vTbData[iTb]->iPrevCont >= -1)); + vTbData[iTb]->iPrevCont = -1; // reset (local copy only) + } + } + } - // find free container - for (size_t iCont = DOCKCONT_MAX, len = _vContainer.size(); iCont < len; ++iCont) - { - if (pArrayPos[iCont] == FALSE) - { - // and test if container is hidden - if (!_vContainer[iCont]->isVisible()) - { + // find free container + for (size_t iCont = DOCKCONT_MAX, len = dockingContVectorSize; iCont < len; ++iCont) + { + if (pArrayPos[iCont] == FALSE) + { + // and test if container is hidden + if (!_vContainer[iCont]->isVisible()) + { iRetCont = static_cast(iCont); - break; - } - } - } + break; + } + } + } - delete [] pPrevDockList; + delete [] pPrevDockList; - // search for empty arrays - return iRetCont; + // search for empty arrays + return iRetCont; }