From 73defc20d07e8bd8f38c3d7ec3f5913cf1a2167b Mon Sep 17 00:00:00 2001 From: d1str4ught <> Date: Mon, 9 Feb 2026 02:25:35 +0100 Subject: [PATCH 1/2] crash fix: when __ClearReserveDeleteWindowList() was destroying Windows, some might have pushed it's children for deletion to m_ReserveDeleteWindowList, invalidating iterators --- src/EterPythonLib/PythonWindowManager.cpp | 22 ++++---- src/EterPythonLib/PythonWindowManager.h | 61 ++++++++++++----------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/EterPythonLib/PythonWindowManager.cpp b/src/EterPythonLib/PythonWindowManager.cpp index 3c22f6a..f666efe 100644 --- a/src/EterPythonLib/PythonWindowManager.cpp +++ b/src/EterPythonLib/PythonWindowManager.cpp @@ -75,6 +75,7 @@ namespace UI void CWindowManager::Destroy() { __ClearReserveDeleteWindowList(); + #ifdef __WINDOW_LEAK_CHECK__ std::set::iterator i; for (i=gs_kSet_pkWnd.begin(); i!=gs_kSet_pkWnd.end(); ++i) @@ -430,7 +431,7 @@ namespace UI pParentWin->DeleteChild(pWin); } pWin->Clear(); - m_ReserveDeleteWindowList.push_back(pWin); + m_ReserveDeleteWindowList.insert(pWin); } BOOL CWindowManager::IsDragging() @@ -710,16 +711,17 @@ namespace UI void CWindowManager::__ClearReserveDeleteWindowList() { - for (TWindowContainer::iterator itor = m_ReserveDeleteWindowList.begin(); itor != m_ReserveDeleteWindowList.end(); ++itor) - { - CWindow * pWin = *itor; -#ifdef __WINDOW_LEAK_CHECK__ - gs_kSet_pkWnd.erase(pWin); -#endif - delete pWin; - } - m_ReserveDeleteWindowList.clear(); + while (!m_ReserveDeleteWindowList.empty()) { + auto tmp = m_ReserveDeleteWindowList; + m_ReserveDeleteWindowList.clear(); + for (CWindow* pWin : tmp) { +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.erase(pWin); +#endif + delete pWin; + } + } } void CWindowManager::Update() diff --git a/src/EterPythonLib/PythonWindowManager.h b/src/EterPythonLib/PythonWindowManager.h index 40abd42..3c386b7 100644 --- a/src/EterPythonLib/PythonWindowManager.h +++ b/src/EterPythonLib/PythonWindowManager.h @@ -1,4 +1,5 @@ #pragma once +#include namespace UI { @@ -144,44 +145,44 @@ namespace UI void __ClearReserveDeleteWindowList(); private: - long m_lWidth; - long m_lHeight; + long m_lWidth; + long m_lHeight; - int m_iVres; - int m_iHres; + int m_iVres; + int m_iHres; - long m_lMouseX, m_lMouseY; - long m_lDragX, m_lDragY; - long m_lPickedX, m_lPickedY; + long m_lMouseX, m_lMouseY; + long m_lDragX, m_lDragY; + long m_lPickedX, m_lPickedY; - BOOL m_bOnceIgnoreMouseLeftButtonUpEventFlag; - int m_iIgnoreEndTime; + BOOL m_bOnceIgnoreMouseLeftButtonUpEventFlag; + int m_iIgnoreEndTime; // Attaching Icon - PyObject * m_poMouseHandler; - BOOL m_bAttachingFlag; - DWORD m_dwAttachingType; - DWORD m_dwAttachingIndex; - DWORD m_dwAttachingSlotNumber; - BYTE m_byAttachingIconWidth; - BYTE m_byAttachingIconHeight; + PyObject * m_poMouseHandler; + BOOL m_bAttachingFlag; + DWORD m_dwAttachingType; + DWORD m_dwAttachingIndex; + DWORD m_dwAttachingSlotNumber; + BYTE m_byAttachingIconWidth; + BYTE m_byAttachingIconHeight; // Attaching Icon - CWindow * m_pActiveWindow; - TWindowContainer m_ActiveWindowList; - CWindow * m_pLockWindow; - TWindowContainer m_LockWindowList; - CWindow * m_pPointWindow; - CWindow * m_pLeftCaptureWindow; - CWindow * m_pRightCaptureWindow; - CWindow * m_pMiddleCaptureWindow; - TKeyCaptureWindowMap m_KeyCaptureWindowMap; - TWindowContainer m_ReserveDeleteWindowList; - TWindowContainer m_PickAlwaysWindowList; + CWindow * m_pActiveWindow; + TWindowContainer m_ActiveWindowList; + CWindow * m_pLockWindow; + TWindowContainer m_LockWindowList; + CWindow * m_pPointWindow; + CWindow * m_pLeftCaptureWindow; + CWindow * m_pRightCaptureWindow; + CWindow * m_pMiddleCaptureWindow; + TKeyCaptureWindowMap m_KeyCaptureWindowMap; + std::unordered_set m_ReserveDeleteWindowList; + TWindowContainer m_PickAlwaysWindowList; - CWindow * m_pRootWindow; - TWindowContainer m_LayerWindowList; - TLayerContainer m_LayerWindowMap; + CWindow * m_pRootWindow; + TWindowContainer m_LayerWindowList; + TLayerContainer m_LayerWindowMap; }; PyObject * BuildEmptyTuple(); From 6929730dd6e9d84bdd03d9c60a72f0c094e2cb3a Mon Sep 17 00:00:00 2001 From: SuntrustDev <19979417+SunTrustDev@users.noreply.github.com> Date: Mon, 9 Feb 2026 02:41:59 +0100 Subject: [PATCH 2/2] Change from korean_tolower to ascii_tolower for better understandability --- src/EterBase/Stl.cpp | 5 ++--- src/EterBase/Stl.h | 2 +- src/EterBase/Utils.cpp | 12 ++++++------ src/EterLib/Resource.cpp | 2 +- src/EterLib/ResourceManager.cpp | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/EterBase/Stl.cpp b/src/EterBase/Stl.cpp index 14cfad5..789ccd3 100644 --- a/src/EterBase/Stl.cpp +++ b/src/EterBase/Stl.cpp @@ -3,13 +3,12 @@ static std::list s_stList; -char korean_tolower(const char c) +char ascii_tolower(const char c) { char ret = c; if (c >= 'A' && c <= 'Z') ret = c - 'A' + 'a'; - assert(ret == tolower(c)); return ret; } @@ -25,7 +24,7 @@ std::string& stl_static_string(const char * c_sz) void stl_lowers(std::string& rstRet) { for (size_t i = 0; i < rstRet.length(); ++i) - rstRet[i] = korean_tolower(rstRet[i]); + rstRet[i] = ascii_tolower(rstRet[i]); } int split_string(const std::string& input, const std::string& delimiter, std::vector& results, bool includeEmpties) diff --git a/src/EterBase/Stl.h b/src/EterBase/Stl.h index bc74865..48d844e 100644 --- a/src/EterBase/Stl.h +++ b/src/EterBase/Stl.h @@ -24,7 +24,7 @@ #pragma warning ( pop ) -extern char korean_tolower(const char c); +extern char ascii_tolower(const char c); extern std::string& stl_static_string(const char* c_sz); extern void stl_lowers(std::string& rstRet); extern int split_string(const std::string & input, const std::string & delimiter, std::vector& results, bool includeEmpties); diff --git a/src/EterBase/Utils.cpp b/src/EterBase/Utils.cpp index bd185f5..c4cf54e 100644 --- a/src/EterBase/Utils.cpp +++ b/src/EterBase/Utils.cpp @@ -10,7 +10,7 @@ #include "Utils.h" #include "filedir.h" -char korean_tolower(const char c); +char ascii_tolower(const char c); const char* CreateTempFileName(const char* c_pszPrefix) { @@ -293,7 +293,7 @@ void StringLowers(char * String) { for (DWORD i = 0; i < strlen(String); ++i) { - String[i] = korean_tolower(String[i]); + String[i] = ascii_tolower(String[i]); } } @@ -304,7 +304,7 @@ void StringPath(std::string & rString) if (rString[i] == '\\') rString[i] = '/'; else - rString[i] = korean_tolower(rString[i]); + rString[i] = ascii_tolower(rString[i]); } } @@ -315,7 +315,7 @@ void StringPath(char * pString) if (pString[i] == '\\') pString[i] = '/'; else - pString[i] = korean_tolower(pString[i]); + pString[i] = ascii_tolower(pString[i]); } } @@ -326,7 +326,7 @@ void StringPath(const char * c_szSrc, char * szDest) if (c_szSrc[i] == '\\') szDest[i] = '/'; else - szDest[i] = korean_tolower(c_szSrc[i]); + szDest[i] = ascii_tolower(c_szSrc[i]); } } @@ -340,7 +340,7 @@ void StringPath(const char * c_szSrc, std::string & rString) if (c_szSrc[i] == '\\') rString[i] = '/'; else - rString[i] = korean_tolower(c_szSrc[i]); + rString[i] = ascii_tolower(c_szSrc[i]); } } diff --git a/src/EterLib/Resource.cpp b/src/EterLib/Resource.cpp index d21c0b0..915e319 100644 --- a/src/EterLib/Resource.cpp +++ b/src/EterLib/Resource.cpp @@ -120,7 +120,7 @@ int CResource::ConvertPathName(const char * c_szPathName, char * pszRetPathName, if (*pc == '/') *(pszRetPathName++) = '\\'; else - *(pszRetPathName++) = (char) korean_tolower(*pc); + *(pszRetPathName++) = (char) ascii_tolower(*pc); } *pszRetPathName = '\0'; diff --git a/src/EterLib/ResourceManager.cpp b/src/EterLib/ResourceManager.cpp index 777a831..4dd4df2 100644 --- a/src/EterLib/ResourceManager.cpp +++ b/src/EterLib/ResourceManager.cpp @@ -236,7 +236,7 @@ int __ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retL if (*pc == '/') *(pszRetPathName++) = '\\'; else - *(pszRetPathName++) = (char) korean_tolower(*pc); + *(pszRetPathName++) = (char) ascii_tolower(*pc); } *pszRetPathName = '\0'; @@ -374,7 +374,7 @@ DWORD CResourceManager::__GetFileCRC(const char * c_szFileName, const char ** c_ if (src[len]=='/') dst[len] = '\\'; else - dst[len] = (char) korean_tolower(src[len]); + dst[len] = (char) ascii_tolower(src[len]); ++len; }