From e993abcdd4bf73b4e32013bf178ceeb9f2c3c647 Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Wed, 9 Feb 2022 02:02:36 +0100 Subject: [PATCH] Memory issues fixing and hardening --- grepWinNP3/grepWinNP3.vcxproj | 8 +- minipath/src/Dlapi.c | 18 +-- src/Config/Config.cpp | 15 +- src/Config/SimpleIni.h | 4 +- src/DarkMode/DarkMode.cpp | 8 + src/Dialogs.c | 14 +- src/Dlapi.c | 7 +- src/Dlapi.h | 2 +- src/Edit.c | 52 +++---- src/EncodingDetection.cpp | 9 ++ src/Helpers.c | 27 +++- src/Helpers.h | 39 +++-- src/MuiLanguage.c | 6 +- src/Notepad3.c | 139 +++++++++++++----- src/Notepad3.ver | 2 +- src/PathLib.c | 2 +- src/Print.cpp | 12 +- src/SciCall.h | 2 +- src/Styles.c | 8 + src/Styles.h | 1 + src/TypeDefs.h | 3 + src/Version.h | 2 +- src/crypto/crypto.h | 7 +- .../Sample_JSON (issue #3070).json | 2 +- 24 files changed, 261 insertions(+), 128 deletions(-) diff --git a/grepWinNP3/grepWinNP3.vcxproj b/grepWinNP3/grepWinNP3.vcxproj index 39f7b3dc4..82b4835fb 100644 --- a/grepWinNP3/grepWinNP3.vcxproj +++ b/grepWinNP3/grepWinNP3.vcxproj @@ -151,7 +151,7 @@ Disabled Use WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDebug + MultiThreadedDebugDLL Level4 stdcpplatest true @@ -186,7 +186,7 @@ Disabled Use WIN64;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDebug + MultiThreadedDebugDLL Level4 stdcpplatest true @@ -221,7 +221,7 @@ true Use WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded + MultiThreadedDLL Level4 stdcpplatest AnySuitable @@ -303,7 +303,7 @@ true Use WIN64;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded + MultiThreadedDLL Level4 stdcpplatest AnySuitable diff --git a/minipath/src/Dlapi.c b/minipath/src/Dlapi.c index 9efcf37ad..38655dbec 100644 --- a/minipath/src/Dlapi.c +++ b/minipath/src/Dlapi.c @@ -16,6 +16,7 @@ #define _WIN32_WINNT 0x601 #include #include +#include #include #include #include @@ -147,19 +148,16 @@ BOOL DirList_Destroy(HWND hwnd) // BOOL DirList_StartIconThread(HWND hwnd) { - - DWORD dwtid; LPDLDATA lpdl = (LPVOID)GetProp(hwnd,pDirListProp); DirList_TerminateIconThread(hwnd); ResetEvent(lpdl->hExitThread); - //ResetEvent(lpdl->hTerminatedThread); + ResetEvent(lpdl->hTerminatedThread); - CreateThread(NULL,0,DirList_IconThread,(LPVOID)lpdl,0,&dwtid); + _beginthread(DirList_IconThread, 0, (void*)lpdl); return TRUE; - } @@ -189,7 +187,6 @@ BOOL DirList_TerminateIconThread(HWND hwnd) SetEvent(lpdl->hTerminatedThread); return TRUE; - } @@ -418,8 +415,8 @@ DWORD WINAPI DirList_IconThread(LPVOID lpParam) // Exit immediately if DirList_Fill() hasn't been called if (!lpdl->lpsf) { SetEvent(lpdl->hTerminatedThread); - ExitThread(0); - //return(0); + _endthread(); + return(0); } hwnd = lpdl->hwnd; @@ -499,9 +496,8 @@ DWORD WINAPI DirList_IconThread(LPVOID lpParam) CoUninitialize(); SetEvent(lpdl->hTerminatedThread); - ExitThread(0); - //return(0); - + _endthread(); + return(0); } diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index e5b03c5fa..213b2eb2b 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -22,6 +22,14 @@ #define NTDDI_VERSION 0x06010000 /*NTDDI_WIN7*/ #endif +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif + #define VC_EXTRALEAN 1 #define WIN32_LEAN_AND_MEAN 1 //#define NOMINMAX 1 @@ -1530,8 +1538,8 @@ void LoadSettings() } Settings.PrintZoom = clampi(iPrintZoom, SC_MIN_ZOOM_LEVEL, SC_MAX_ZOOM_LEVEL); - WCHAR localeInfo[3]; - GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3); + WCHAR localeInfo[SMALL_BUFFER]; + GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, COUNTOF(localeInfo)); LONG const _margin = (localeInfo[0] == L'0') ? 2000L : 1000L; // Metric system. L'1' is US System Defaults.PrintMargin.left = _margin; Settings.PrintMargin.left = clampi(IniSectionGetInt(IniSecSettings, L"PrintMarginLeft", Defaults.PrintMargin.left), 0, 40000); @@ -2660,7 +2668,6 @@ void MRU_Save(LPMRULIST pmru) } } } - CloseSettingsFile(true, bOpenedByMe); } } @@ -2698,7 +2705,6 @@ bool MRU_MergeSave(LPMRULIST pmru, bool bAddFiles, bool bRelativePath, bool bUne } MRU_Save(pmruBase); - MRU_Destroy(pmruBase); pmruBase = NULL; CloseSettingsFile(bOpenedByMe, bOpenedByMe); @@ -2709,6 +2715,7 @@ bool MRU_MergeSave(LPMRULIST pmru, bool bAddFiles, bool bRelativePath, bool bUne return false; } + // //////////////////////////////////////////////////////////////////////////// // Some C++ Extentions for Notepad3 // //////////////////////////////////////////////////////////////////////////// diff --git a/src/Config/SimpleIni.h b/src/Config/SimpleIni.h index 90a760d7f..fe24408b0 100644 --- a/src/Config/SimpleIni.h +++ b/src/Config/SimpleIni.h @@ -255,8 +255,8 @@ # include #endif // SI_SUPPORT_IOSTREAMS -#ifdef _DEBUG -# ifndef assert +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#ifndef assert # include # endif # define SI_ASSERT(x) assert(x) diff --git a/src/DarkMode/DarkMode.cpp b/src/DarkMode/DarkMode.cpp index e5dfff577..b02ba859b 100644 --- a/src/DarkMode/DarkMode.cpp +++ b/src/DarkMode/DarkMode.cpp @@ -14,6 +14,14 @@ * * *******************************************************************************/ +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif + #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include diff --git a/src/Dialogs.c b/src/Dialogs.c index 3cd7d53f3..5396c3e63 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -2137,15 +2138,7 @@ bool AddToFavDlg(HWND hwnd, const HPATHL hTargetPth) // FileMRUDlgProc() // // -typedef struct tagIconThreadInfo { - HWND hwnd; // HWND of ListView Control - HANDLE hThread; // Thread Handle - HANDLE hExitThread; // Flag is set when Icon Thread should terminate - HANDLE hTerminatedThread; // Flag is set when Icon Thread has terminated - -} ICONTHREADINFO, *LPICONTHREADINFO; - -DWORD WINAPI FileMRUIconThread(LPVOID lpParam) +unsigned int WINAPI FileMRUIconThread(LPVOID lpParam) { BackgroundWorker *worker = (BackgroundWorker *)lpParam; @@ -2218,6 +2211,7 @@ DWORD WINAPI FileMRUIconThread(LPVOID lpParam) } CoUninitialize(); + BackgroundWorker_End(0); return 0; } @@ -2489,7 +2483,7 @@ CASE_WM_CTLCOLOR_SET: DialogEnableControl(hwnd, IDOK, (cnt > 0)); DialogEnableControl(hwnd, IDC_REMOVE, (cnt > 0)); - worker->workerThread = CreateThread(NULL, 0, FileMRUIconThread, (LPVOID)worker, 0, NULL); + BackgroundWorker_Start(worker, FileMRUIconThread, worker); } break; diff --git a/src/Dlapi.c b/src/Dlapi.c index c0e110182..8ca3366de 100644 --- a/src/Dlapi.c +++ b/src/Dlapi.c @@ -45,8 +45,8 @@ typedef struct tagDLDATA { // dl //==== Property Name ========================================================== -static const WCHAR *pDirListProp = L"DirListData"; +static const WCHAR *pDirListProp = L"DirListData"; //============================================================================= @@ -137,7 +137,7 @@ void DirList_StartIconThread(HWND hwnd) LPDLDATA lpdl = (LPDLDATA)GetProp(hwnd, pDirListProp); BackgroundWorker_Cancel(&lpdl->worker); - lpdl->worker.workerThread = CreateThread(NULL, 0, DirList_IconThread, (LPVOID)lpdl, 0, NULL); + BackgroundWorker_Start(&lpdl->worker, DirList_IconThread, lpdl); } @@ -333,7 +333,7 @@ int DirList_Fill(HWND hwnd,LPCWSTR lpszDir,DWORD grfFlags,LPCWSTR lpszFileSpec, // // Thread to extract file icons in the background // -DWORD WINAPI DirList_IconThread(LPVOID lpParam) +unsigned int WINAPI DirList_IconThread(LPVOID lpParam) { LPDLDATA lpdl = (LPDLDATA)lpParam; BackgroundWorker *worker = &lpdl->worker; @@ -432,6 +432,7 @@ DWORD WINAPI DirList_IconThread(LPVOID lpParam) } CoUninitialize(); + BackgroundWorker_End(0); return 0; } diff --git a/src/Dlapi.h b/src/Dlapi.h index 460098fd3..d7b76e0e6 100644 --- a/src/Dlapi.h +++ b/src/Dlapi.h @@ -61,7 +61,7 @@ int DirList_Fill(HWND hwnd,LPCWSTR lpszDir,DWORD grfFlags,LPCWSTR lpszFileSpec,b //==== DlIconThread() ========================================================= -DWORD WINAPI DirList_IconThread(LPVOID lpParam); +unsigned int WINAPI DirList_IconThread(LPVOID lpParam); //==== DlGetDispInfo() ======================================================== diff --git a/src/Edit.c b/src/Edit.c index 8ff840d41..b19c6f1e7 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -2223,10 +2223,13 @@ void EditChar2Hex(HWND hwnd) size_t const alloc = (count + 1) * (2 + MAX_ESCAPE_HEX_DIGIT) + 1; char* const ch = (char*)AllocMem(alloc, HEAP_ZERO_MEMORY); WCHAR* const wch = (WCHAR*)AllocMem(alloc * sizeof(WCHAR), HEAP_ZERO_MEMORY); + if (!ch || !wch) { + return; + } SciCall_GetSelText(ch); int const nchars = (DocPos)MultiByteToWideChar(Encoding_SciCP, 0, ch, -1, wch, (int)alloc) - 1; // '\0' - memset(ch, 0, alloc); + SecureZeroMemory(ch, alloc); for (int i = 0, j = 0; i < nchars; ++i) { if (wch[i] <= 0xFF) { @@ -5838,7 +5841,7 @@ static DocPos _FindInTarget(LPCWSTR wchFind, int sFlags, { UNREFERENCED_PARAMETER(bForceNext); - static char* chFind = NULL; // for speed (realloc()) + static char chFind[8192] = { '\0' }; // max find buffer DocPos iPos = -1LL; // not found @@ -5857,9 +5860,7 @@ static DocPos _FindInTarget(LPCWSTR wchFind, int sFlags, SciCall_SetSearchFlags(sFlags); SciCall_SetTargetRange(start, stop); - int const len = WideCharToMultiByte(Encoding_SciCP, 0, wchFind, -1, NULL, 0, NULL, NULL); - chFind = ReAllocMem(chFind, len * sizeof(char), HEAP_ZERO_MEMORY); - WideCharToMultiByte(Encoding_SciCP, 0, wchFind, -1, chFind, len, NULL, NULL); + DocPos const len = (DocPos)WideCharToMultiByte(Encoding_SciCP, 0, wchFind, -1, chFind, COUNTOF(chFind), NULL, NULL); iPos = SciCall_SearchInTarget(len - 1, chFind); // handle next in case of zero-length-matches (regex) ! @@ -7543,14 +7544,12 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd DocPos iFindLength = 0; - static LPWSTR pwchText = NULL; + char chText[2048] = { L'\0'}; + WCHAR wchText[2048] = { L'\0'}; if (StrIsEmpty(wchFind)) { - static char* pchText = NULL; - int const len = max_i(WideCharToMultiByte(Encoding_SciCP, 0, wchFind, -1, NULL, 0, NULL, NULL), 256); - pchText = ReAllocMem(pchText, len * sizeof(char), HEAP_ZERO_MEMORY); - WideCharToMultiByte(Encoding_SciCP, 0, wchFind, -1, pchText, len, NULL, NULL); + WideCharToMultiByte(Encoding_SciCP, 0, wchFind, -1, chText, COUNTOF(chText), NULL, NULL); if (SciCall_IsSelectionEmpty()) { // nothing selected, get word under caret if flagged @@ -7563,7 +7562,8 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd } iFindLength = (iWordEnd - iWordStart); - StringCchCopyNA(pchText, SizeOfMem(pchText)/sizeof(char), SciCall_GetRangePointer(iWordStart, iFindLength), iFindLength); + StringCchCopyNA(chText, COUNTOF(chText), SciCall_GetRangePointer(iWordStart, iFindLength), iFindLength); + } else { __leave; // no pattern, no selection and no word mark chosen } @@ -7576,21 +7576,27 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd // get current selection DocPos const iSelStart = SciCall_GetSelectionStart(); DocPos const iSelEnd = SciCall_GetSelectionEnd(); - DocPos const iSelCount = (iSelEnd - iSelStart); + //DocPos const iSelCount = (iSelEnd - iSelStart); // if multiple lines are selected exit if (SciCall_LineFromPosition(iSelStart) != SciCall_LineFromPosition(iSelEnd)) { __leave; } - iFindLength = SciCall_GetSelText(pchText); + DocPosU const iSelLen = SciCall_GetSelText(NULL); + if (iSelLen >= COUNTOF(chText)) { + __leave; + } + + iFindLength = SciCall_GetSelText(chText); + chText[iFindLength] = '\0'; // exit if selection is not a word and Match whole words only is enabled if (sFlags & SCFIND_WHOLEWORD) { - DocPos iSelStart2 = 0; + DocPosU iSelStart2 = 0; const char* delims = (Settings.AccelWordNavigation ? DelimCharsAccel : DelimChars); - while ((iSelStart2 <= iSelCount) && pchText[iSelStart2]) { - if (StrChrIA(delims, pchText[iSelStart2])) { + while ((iSelStart2 <= iSelLen) && chText[iSelStart2]) { + if (StrChrIA(delims, chText[iSelStart2])) { __leave; } ++iSelStart2; @@ -7598,17 +7604,13 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd } } - int const length = MultiByteToWideChar(Encoding_SciCP, 0, pchText, (int)iFindLength, NULL, 0); - pwchText = ReAllocMem(pwchText, max_i(length + 1, 256) * sizeof(WCHAR), HEAP_ZERO_MEMORY); - MultiByteToWideChar(Encoding_SciCP, 0, pchText, (int)iFindLength, pwchText, (int)(SizeOfMem(pwchText) / sizeof(WCHAR))); + MultiByteToWideChar(Encoding_SciCP, 0, chText, (int)iFindLength, wchText, (int)COUNTOF(wchText)); } else { - - pwchText = ReAllocMem(pwchText, max_s(StringCchLen(wchFind, 0) + 1, 256) * sizeof(WCHAR), HEAP_ZERO_MEMORY); - StringCchCopy(pwchText, SizeOfMem(pwchText) / sizeof(WCHAR), wchFind); + StringCchCopy(wchText, COUNTOF(wchText), wchFind); } - if (StrIsNotEmpty(pwchText)) { + if (StrIsNotEmpty(wchText)) { if (bMultiSel) { SciCall_ClearSelections(); @@ -7620,7 +7622,7 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd DocPos start = rangeStart; DocPos end = rangeEnd; - DocPos iPos = _FindInTarget(pwchText, sFlags, &start, &end, false, FRMOD_NORM); + DocPos iPos = _FindInTarget(wchText, sFlags, &start, &end, false, FRMOD_NORM); DocPosU count = 0; while ((iPos >= 0LL) && (start <= rangeEnd)) { @@ -7640,7 +7642,7 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd ++count; start = end; end = rangeEnd; - iPos = _FindInTarget(pwchText, sFlags, &start, &end, true, FRMOD_NORM); + iPos = _FindInTarget(wchText, sFlags, &start, &end, true, FRMOD_NORM); }; Globals.iMarkOccurrencesCount = count; diff --git a/src/EncodingDetection.cpp b/src/EncodingDetection.cpp index 1e40d7c4e..5fb6eac55 100644 --- a/src/EncodingDetection.cpp +++ b/src/EncodingDetection.cpp @@ -22,6 +22,15 @@ #if !defined(NTDDI_VERSION) #define NTDDI_VERSION 0x06010000 /*NTDDI_WIN7*/ #endif + +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif + #define VC_EXTRALEAN 1 #define WIN32_LEAN_AND_MEAN 1 #define NOMINMAX 1 diff --git a/src/Helpers.c b/src/Helpers.c index 0fd2866a1..97d07b742 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -600,9 +600,20 @@ void BackgroundWorker_Init(BackgroundWorker* worker, HWND hwnd, HPATHL hFilePath worker->hFilePath = hFilePath; } -void BackgroundWorker_Stop(BackgroundWorker *worker) { +void BackgroundWorker_Start(BackgroundWorker* worker, _beginthreadex_proc_type routine, LPVOID property) +{ + //~worker->workerThread = CreateThread(NULL, 0, routine, property, 0, NULL); // MD(d) dll + worker->workerThread = (HANDLE)_beginthreadex(NULL, 0, routine, property, 0, NULL); // MT(d) static +} + +void BackgroundWorker_End(unsigned int retcode) +{ + _endthreadex(retcode); +} + +static void _BackgroundWorker_Stop(BackgroundWorker* worker) { SetEvent(worker->eventCancel); - HANDLE workerThread = worker->workerThread; + HANDLE const workerThread = worker->workerThread; if (workerThread) { worker->workerThread = NULL; while (WaitForSingleObject(workerThread, 0) != WAIT_OBJECT_0) { @@ -616,13 +627,13 @@ void BackgroundWorker_Stop(BackgroundWorker *worker) { } } -void BackgroundWorker_Cancel(BackgroundWorker *worker) { - BackgroundWorker_Stop(worker); +void BackgroundWorker_Cancel(BackgroundWorker* worker) { + _BackgroundWorker_Stop(worker); ResetEvent(worker->eventCancel); } -void BackgroundWorker_Destroy(BackgroundWorker *worker) { - BackgroundWorker_Stop(worker); +void BackgroundWorker_Destroy(BackgroundWorker* worker) { + _BackgroundWorker_Stop(worker); CloseHandle(worker->eventCancel); } @@ -1152,8 +1163,8 @@ bool SplitFilePathLineNum(LPWSTR lpszPath, int* lineNum) // size_t FormatNumberStr(LPWSTR lpNumberStr, size_t cch, int fixedWidth) { - static WCHAR szSep[5] = { L'\0' }; - static WCHAR szGrp[11] = { L'\0' }; + static WCHAR szSep[SMALL_BUFFER] = { L'\0' }; + static WCHAR szGrp[SMALL_BUFFER] = { L'\0' }; static int iPlace[4] = {-1,-1,-1,-1}; if (StrIsEmpty(lpNumberStr)) { diff --git a/src/Helpers.h b/src/Helpers.h index f498eece2..657d934ab 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -19,9 +19,10 @@ #include "TypeDefs.h" +#include +#include #include #include -#include #include #include "Scintilla.h" @@ -55,11 +56,26 @@ // ============================================================================ +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#ifndef _DEBUG +#define _DEBUG 1 +#endif +#ifndef DEBUG +#define DEBUG 1 +#endif +inline void* reallocz(void* pMem, size_t numBytes) { void* pM = realloc(pMem, numBytes); if (pM) memset(pM, 0, numBytes); return pM; } +#define AllocMem(B, F) (((F)&HEAP_ZERO_MEMORY) ? calloc(1, B) : malloc(B)) +#define ReAllocMem(M, B, F) ((M) ? ((_msize(M) >= (B)) ? (((F)&HEAP_ZERO_MEMORY) ? (memset(M, 0, B), (M)) : (M)) : (((F)&HEAP_ZERO_MEMORY) ? reallocz(M, B) : realloc(M, B))) : AllocMem(B, F)) +#define FreeMem(M) ((M ? (free(M)) : NOOP), true) +#define SizeOfMem(M) ((M) ? _msize(M) : 0) + +#else // RELASE VERSION + // direct heap allocation #if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) -#define DEFAULT_ALLOC_FLAGS (HEAP_GENERATE_EXCEPTIONS) +#define DEFAULT_ALLOC_FLAGS (HEAP_GENERATE_EXCEPTIONS | HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_CREATE_HARDENED) #else -#define DEFAULT_ALLOC_FLAGS (0) +#define DEFAULT_ALLOC_FLAGS (HEAP_CREATE_HARDENED) #endif inline LPVOID AllocMem(size_t numBytes, DWORD dwFlags) @@ -73,7 +89,7 @@ inline LPVOID ReAllocMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) size_t const memSize = HeapSize(Globals.hndlProcessHeap, 0, lpMem); if (memSize >= numBytes) { if (dwFlags & HEAP_ZERO_MEMORY) { - ZeroMemory(lpMem, memSize); + SecureZeroMemory(lpMem, memSize); } return lpMem; } @@ -82,16 +98,18 @@ inline LPVOID ReAllocMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) return HeapAlloc(Globals.hndlProcessHeap, (dwFlags | DEFAULT_ALLOC_FLAGS), numBytes); } -inline bool FreeMem(LPVOID lpMemory) +inline bool FreeMem(LPVOID lpMem) { - return (lpMemory ? HeapFree(Globals.hndlProcessHeap, 0, lpMemory) : true); + return (lpMem ? HeapFree(Globals.hndlProcessHeap, 0, lpMem) : true); } -inline size_t SizeOfMem(LPCVOID lpMemory) +inline size_t SizeOfMem(LPCVOID lpMem) { - return (lpMemory ? HeapSize(Globals.hndlProcessHeap, 0, lpMemory) : 0); + return (lpMem ? HeapSize(Globals.hndlProcessHeap, 0, lpMem) : 0); } +#endif + // ============================================================================ #if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) @@ -381,10 +399,11 @@ typedef struct BackgroundWorker { } BackgroundWorker; void BackgroundWorker_Init(BackgroundWorker* worker, HWND hwnd, HPATHL hFilePath); +void BackgroundWorker_Start(BackgroundWorker* worker, _beginthreadex_proc_type routine, LPVOID property); +void BackgroundWorker_End(unsigned int retcode); void BackgroundWorker_Cancel(BackgroundWorker *worker); void BackgroundWorker_Destroy(BackgroundWorker *worker); -#define BackgroundWorker_Continue(worker) \ - (WaitForSingleObject((worker)->eventCancel, 0) != WAIT_OBJECT_0) +__forceinline bool BackgroundWorker_Continue(BackgroundWorker* worker) { return (WaitForSingleObject(worker->eventCancel, 0) != WAIT_OBJECT_0); } bool BitmapMergeAlpha(HBITMAP hbmp,COLORREF crDest); bool BitmapAlphaBlend(HBITMAP hbmp,COLORREF crDest,BYTE alpha); diff --git a/src/MuiLanguage.c b/src/MuiLanguage.c index 3ca8bce5c..ec71c180c 100644 --- a/src/MuiLanguage.c +++ b/src/MuiLanguage.c @@ -140,7 +140,7 @@ static void SetMuiLocaleAll(LPCWSTR pszLocaleStr) { if (pszLocaleCur && (StringCchCompareXI(pszLocaleStr, pszLocaleCur) != 0)) { //const _locale_t pCurLocale = _get_current_locale(); _wsetlocale(LC_ALL, L""); // system standard -#ifdef _DEBUG +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) WCHAR msg[128]; StringCchPrintf(msg, COUNTOF(msg), L"Can't set desired locale '%s', using '%s' instead!", pszLocaleStr, pszLocaleCur ? pszLocaleCur : L""); @@ -276,7 +276,7 @@ static unsigned _CheckAvailableLanguageDLLs() if (IsValidLocaleName(MUI_LanguageDLLs[lng].LocaleName)) { -#ifdef _DEBUG +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) WCHAR wchLngLocalName[LOCALE_NAME_MAX_LENGTH + 1]; if (ResolveLocaleName(MUI_LanguageDLLs[lng].LocaleName, wchLngLocalName, COUNTOF(wchLngLocalName))) { //~StringCchCopy(MUI_LanguageDLLs[lng].LocaleName, COUNTOF(MUI_LanguageDLLs[lng].LocaleName), wchLngLocalName); // put back resolved name @@ -378,7 +378,7 @@ unsigned LoadLanguageResources(LPCWSTR pLocaleName) { // using SetProcessPreferredUILanguages is recommended for new applications (esp. multi-threaded applications) SetProcessPreferredUILanguages(0, L"\0\0", &langCount); // clear if (!SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, tchUserLangMultiStrg, &langCount) || (langCount == 0)) { -#ifdef _DEBUG +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) MsgBoxLastError(L"Trying to set preferred Language!", ERROR_RESOURCE_LANG_NOT_FOUND); #endif } diff --git a/src/Notepad3.c b/src/Notepad3.c index ab1fc14cc..328f46663 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -16,7 +16,12 @@ #include "Helpers.h" +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#define _CRTDBG_MAP_ALLOC +#include #include +#endif + #include #include #include @@ -44,8 +49,8 @@ #include "DarkMode/DarkMode.h" #include "StyleLexers/EditLexer.h" -#if defined(DEBUG) || defined(_DEBUG) - #if defined(WIN32) && !defined(_WIN64) +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#if defined(WIN32) && !defined(_WIN64) #pragma comment(linker, "/defaultlib:clang_rt.asan-i386.lib") #endif // _WIN64 #endif // DEBUG @@ -254,50 +259,45 @@ static void InitUndoRedoSelection(void* elt) } } - static void DelUndoRedoSelection(void* elt) { UndoRedoSelection_t* selection = (UndoRedoSelection_t*)elt; - if (selection != NULL) { + if (selection != NULL) + { + selection->selMode_undo = SC_SEL_STREAM; + selection->selMode_redo = SC_SEL_STREAM; + if (selection->anchorPos_undo != NULL) { - utarray_clear(selection->anchorPos_undo); utarray_free(selection->anchorPos_undo); selection->anchorPos_undo = NULL; } if (selection->curPos_undo != NULL) { - utarray_clear(selection->curPos_undo); utarray_free(selection->curPos_undo); selection->curPos_undo = NULL; } if (selection->anchorVS_undo != NULL) { - utarray_clear(selection->anchorVS_undo); utarray_free(selection->anchorVS_undo); selection->anchorVS_undo = NULL; } if (selection->curVS_undo != NULL) { - utarray_clear(selection->curVS_undo); utarray_free(selection->curVS_undo); selection->curVS_undo = NULL; } if (selection->anchorPos_redo != NULL) { - utarray_clear(selection->anchorPos_redo); utarray_free(selection->anchorPos_redo); selection->anchorPos_redo = NULL; } if (selection->curPos_redo != NULL) { - utarray_clear(selection->curPos_redo); utarray_free(selection->curPos_redo); selection->curPos_redo = NULL; } if (selection->anchorVS_redo != NULL) { - utarray_clear(selection->anchorVS_redo); utarray_free(selection->anchorVS_redo); selection->anchorVS_redo = NULL; } if (selection->curVS_redo != NULL) { - utarray_clear(selection->curVS_redo); utarray_free(selection->curVS_redo); selection->curVS_redo = NULL; } @@ -810,6 +810,8 @@ static void _InitGlobals() s_pthArgFilePath = Path_Allocate(NULL); + // don't allow empty extensions settings => use default ext + Style_InitFileExtensions(); } @@ -836,8 +838,8 @@ static void _CleanUpResources(const HWND hwnd, bool bIsInitialized) DL_DELETE(MessageQueue, pmqc); FreeMem(pmqc); } + if (UndoRedoSelectionUTArray != NULL) { - utarray_clear(UndoRedoSelectionUTArray); utarray_free(UndoRedoSelectionUTArray); UndoRedoSelectionUTArray = NULL; } @@ -851,9 +853,9 @@ static void _CleanUpResources(const HWND hwnd, bool bIsInitialized) s_hEventFileDeletedExt = INVALID_HANDLE_VALUE; } - // -------------------------------------- - // Save Settings is done elsewhere before - // -------------------------------------- + // --------------------------------------------- + // Save Settings should be done elsewhere before + // --------------------------------------------- if (Globals.hMainMenu) { DestroyMenu(Globals.hMainMenu); @@ -867,9 +869,6 @@ static void _CleanUpResources(const HWND hwnd, bool bIsInitialized) Scintilla_ReleaseResources(); - OleUninitialize(); - CoUninitialize(); - if (bIsInitialized) { //~UnregisterClass(s_ToolbarWndClassName, Globals.hInstance); UnregisterClass(s_wchWndClass, Globals.hInstance); @@ -877,16 +876,19 @@ static void _CleanUpResources(const HWND hwnd, bool bIsInitialized) ReleaseDarkMode(); + OleUninitialize(); + CoUninitialize(); + + // --- free allocated memory --- + if (s_lpOrigFileArg) { FreeMem(s_lpOrigFileArg); s_lpOrigFileArg = NULL; } - if (_hOldInvalidParamHandler) { - _set_invalid_parameter_handler(_hOldInvalidParamHandler); - } - - // --- free allocated memory --- + MRU_Destroy(Globals.pFileMRU); + MRU_Destroy(Globals.pMRUfind); + MRU_Destroy(Globals.pMRUreplace); StrgDestroy(Settings2.FileDlgFilters); StrgDestroy(Settings2.HyperlinkShellExURLCmdLnArgs); @@ -923,6 +925,54 @@ static void _CleanUpResources(const HWND hwnd, bool bIsInitialized) ThemesItems_Release(); Path_Release(s_hpthRelaunchElevatedFile); + + // --------------------------------------------- + + if (Globals.hDlgIcon256) { + DestroyIcon(Globals.hDlgIcon256); + } + if (Globals.hDlgIcon128) { + DestroyIcon(Globals.hDlgIcon128); + } + if (Globals.hDlgIconBig) { + DestroyIcon(Globals.hDlgIconBig); + } + if (Globals.hDlgIconSmall) { + DestroyIcon(Globals.hDlgIconSmall); + } + if (Globals.hDlgIconPrefs256) { + DestroyIcon(Globals.hDlgIconPrefs256); + } + if (Globals.hDlgIconPrefs128) { + DestroyIcon(Globals.hDlgIconPrefs128); + } + if (Globals.hDlgIconPrefs64) { + DestroyIcon(Globals.hDlgIconPrefs64); + } + if (Globals.hIconMsgUser) { + DestroyIcon(Globals.hIconMsgUser); + } + if (Globals.hIconMsgInfo) { + DestroyIcon(Globals.hIconMsgInfo); + } + if (Globals.hIconMsgWarn) { + DestroyIcon(Globals.hIconMsgWarn); + } + if (Globals.hIconMsgError) { + DestroyIcon(Globals.hIconMsgError); + } + if (Globals.hIconMsgQuest) { + DestroyIcon(Globals.hIconMsgQuest); + } + if (Globals.hIconMsgShield) { + DestroyIcon(Globals.hIconMsgShield); + } + + + // install previous handler + if (_hOldInvalidParamHandler) { + _set_invalid_parameter_handler(_hOldInvalidParamHandler); + } } @@ -942,7 +992,7 @@ void InvalidParameterHandler(const wchar_t* expression, UNREFERENCED_PARAMETER(file); UNREFERENCED_PARAMETER(line); UNREFERENCED_PARAMETER(pReserved); -#ifdef _DEBUG +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) WCHAR msg[256]; StringCchPrintf(msg, COUNTOF(msg), L"Invalid Parameter in function '%s()' - File:'%s' Line:%i !", @@ -960,7 +1010,11 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, { _invalid_parameter_handler const hNewInvalidParamHandler = InvalidParameterHandler; _hOldInvalidParamHandler= _set_invalid_parameter_handler(hNewInvalidParamHandler); + +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetReportMode(_CRT_ASSERT, 0); // Disable the message box for assertions. +#endif _InitGlobals(); InitDarkMode(); @@ -1039,16 +1093,19 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, HRSRC const hRes = FindResourceEx(hInstance, RT_RCDATA, MAKEINTRESOURCE(IDR_STD_DARKMODE_THEME), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); - HGLOBAL const hMem = LoadResource(hInstance, hRes); - DWORD const size = SizeofResource(hInstance, hRes); - const char * const resText = (const char *)LockResource(hMem); - Globals.pStdDarkModeIniStyles = (char *)AllocMem(((size_t)size + 1), 0); - if (Globals.pStdDarkModeIniStyles) { - memcpy_s(Globals.pStdDarkModeIniStyles, size + 1, resText, size); - Globals.pStdDarkModeIniStyles[size] = '\0'; // zero termination + if (hRes) { + HGLOBAL const hMem = LoadResource(hInstance, hRes); + if (hMem) { + const char* const resText = (const char*)LockResource(hMem); + DWORD const size = SizeofResource(hInstance, hRes); + Globals.pStdDarkModeIniStyles = (char*)AllocMem(((size_t)size + 1), 0); + if (Globals.pStdDarkModeIniStyles) { + CopyMemory(Globals.pStdDarkModeIniStyles, resText, size); + Globals.pStdDarkModeIniStyles[size] = '\0'; // zero termination + } + FreeResource(hMem); + } } - FreeResource(hMem); - Style_ImportTheme(-1); // init (!) Style_ImportTheme(Globals.uCurrentThemeIndex); @@ -1206,6 +1263,9 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _CleanUpResources(hwnd, true); +#ifdef _DEBUG + _CrtDumpMemoryLeaks(); +#endif return (int)(msg.wParam); } @@ -1683,7 +1743,6 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow) // undo / redo selections if (UndoRedoSelectionUTArray != NULL) { - utarray_clear(UndoRedoSelectionUTArray); utarray_free(UndoRedoSelectionUTArray); UndoRedoSelectionUTArray = NULL; } @@ -10021,8 +10080,8 @@ static int _SaveUndoSelection() { static DocPosU _s_iSelection = 0; // index - UndoRedoSelection_t sel = INIT_UNDOREDOSEL; - CopyUndoRedoSelection(&sel, NULL); // init + UndoRedoSelection_t sel = INIT_UNDOREDOSEL; // = InitUndoRedoSelection(&sel); + CopyUndoRedoSelection(&sel, NULL); // utarray_new() DocPosU const numOfSel = SciCall_GetSelections(); @@ -10094,6 +10153,9 @@ static int _SaveUndoSelection() //~SciCall_AddUndoAction(token, UNDO_MAY_COALESCE); SciCall_AddUndoAction(token, UNDO_NONE); } + + DelUndoRedoSelection(&sel); // utarray_free() + _s_iSelection = 0; // reset return token; @@ -10346,7 +10408,8 @@ static int _UndoRedoActionMap(int token, const UndoRedoSelection_t** selection) EndUndoAction(curToken); } utarray_clear(UndoRedoSelectionUTArray); - utarray_init(UndoRedoSelectionUTArray, &UndoRedoSelection_icd); + //utarray_free(UndoRedoSelectionUTArray); + //utarray_init(UndoRedoSelectionUTArray, &UndoRedoSelection_icd); uiTokenCnt = 0U; InterlockedExchange(&UndoActionToken, UNDOREDO_FREE); return -1; diff --git a/src/Notepad3.ver b/src/Notepad3.ver index e58cb3989..2c24e1b3d 100644 --- a/src/Notepad3.ver +++ b/src/Notepad3.ver @@ -23,7 +23,7 @@ VS_VERSION_INFO VERSIONINFO FILEVERSION VERSION_FILEVERSION_NUM PRODUCTVERSION VERSION_FILEVERSION_NUM FILEFLAGSMASK 0x3fL -#ifdef _DEBUG +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) FILEFLAGS VS_FF_PATCHED | VS_FF_DEBUG #else FILEFLAGS VS_FF_PATCHED diff --git a/src/PathLib.c b/src/PathLib.c index 1eebe19b6..8082ed68e 100644 --- a/src/PathLib.c +++ b/src/PathLib.c @@ -1371,7 +1371,7 @@ size_t PTHAPI Path_ToShortPathName(HPATHL hpth_in_out) DWORD const _len = GetShortPathNameW(StrgGet(hstr_io), NULL, 0); if (!_len) { -#ifdef DEBUG +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) MsgBoxLastError(L"Path_ToShortPathName()", 0); #endif // DEBUG return 0; diff --git a/src/Print.cpp b/src/Print.cpp index 25538d3b0..e4329ae7d 100644 --- a/src/Print.cpp +++ b/src/Print.cpp @@ -16,6 +16,14 @@ * * *******************************************************************************/ +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif + #if !defined(WINVER) #define WINVER 0x601 /*_WIN32_WINNT_WIN7*/ #endif @@ -226,8 +234,8 @@ extern "C" bool EditPrint(HWND hwnd,LPCWSTR pszDocTitle,LPCWSTR pszPageFormat) // thousandths of inches (HiEnglish) margin values // from the Page Setup dialog to device units. // (There are 2540 hundredths of a mm in an inch.) - WCHAR localeInfo[3]; - GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3); + WCHAR localeInfo[SMALL_BUFFER]; + GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, COUNTOF(localeInfo)); RECT rectSetup; if (localeInfo[0] == L'0') { // Metric system. L'1' is US System diff --git a/src/SciCall.h b/src/SciCall.h index 66586db05..e986fcb36 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -740,7 +740,7 @@ DeclareSciCallR0(IsSelectionRectangle, SELECTIONISRECTANGLE, bool); // length of line w/o line-end chars (full use SciCall_LineLength() #define Sci_GetNetLineLength(line) (SciCall_GetLineEndPosition(line) - SciCall_PositionFromLine(line)) -//~#define Sci_GetDocEndPosition() (SciCall_GetTextLength() - 1) +//~#define Sci_GetDocEndPosition() SciCall_GetTextLength() #define Sci_GetDocEndPosition() SciCall_PositionAfter(SciCall_GetTextLength() - 1) #define Sci_ClampAlpha(alpha) clampi((alpha), SC_ALPHA_TRANSPARENT, SC_ALPHA_OPAQUE) //~SC_ALPHA_NOALPHA diff --git a/src/Styles.c b/src/Styles.c index 98eb82d55..292f36db5 100644 --- a/src/Styles.c +++ b/src/Styles.c @@ -467,6 +467,14 @@ static inline void AppendStyle(LPWSTR lpszStyleDest, size_t cchSizeDest, LPCWSTR //============================================================================= +void Style_InitFileExtensions() +{ + for (int iLexer = 0; iLexer < COUNTOF(g_pLexArray); iLexer++) { + if (StrIsEmpty(g_pLexArray[iLexer]->szExtensions)) { + StringCchCopy(g_pLexArray[iLexer]->szExtensions, COUNTOF(g_pLexArray[iLexer]->szExtensions), g_pLexArray[iLexer]->pszDefExt); + } + } +} //============================================================================= // diff --git a/src/Styles.h b/src/Styles.h index 3d109a309..6a00942fd 100644 --- a/src/Styles.h +++ b/src/Styles.h @@ -29,6 +29,7 @@ int Style_NumOfLexers(); // Number of Lexers in pLexArray +void Style_InitFileExtensions(); void Style_Prerequisites(); bool Style_Import(HWND hwnd); bool Style_ImportTheme(const int iThemeIdx); // -1 => Factory Reset diff --git a/src/TypeDefs.h b/src/TypeDefs.h index 8af546d1c..3ef0eae43 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -23,6 +23,9 @@ #define NTDDI_VERSION 0x06010000 /*NTDDI_WIN7*/ #endif +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#endif + // Want to use std::min and std::max so don't want Windows.h version of min and max #if !defined(NOMINMAX) #define NOMINMAX diff --git a/src/Version.h b/src/Version.h index f8544213f..978ff3807 100644 --- a/src/Version.h +++ b/src/Version.h @@ -36,7 +36,7 @@ #endif -#if defined(_DEBUG) || defined(DEBUG) +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) #pragma message("Debug Build: " _STRG(VERSION_FILEVERSION_LONG)) #else #pragma message("Release Build: " _STRG(VERSION_FILEVERSION_LONG)) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 8e7d0a21f..cd8feadf5 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -3,8 +3,11 @@ #define __CRYPTO_H__ #include -#ifdef _DEBUG -#define BUG1(a,b) { perror("a"); } +#if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) +#define BUG1(a, b) \ + { \ + perror("a"); \ + } #define BUG(a) { perror("a"); } #else #define BUG1(a,b) ((void)0); diff --git a/test/test_files/StyleLexers/styleLexJSON/Sample_JSON (issue #3070).json b/test/test_files/StyleLexers/styleLexJSON/Sample_JSON (issue #3070).json index 4626c21b6..e8aaa5405 100644 --- a/test/test_files/StyleLexers/styleLexJSON/Sample_JSON (issue #3070).json +++ b/test/test_files/StyleLexers/styleLexJSON/Sample_JSON (issue #3070).json @@ -12,7 +12,7 @@ No \\n's!", hexadecimal: 0xdecaf, leadingDecimalPoint: 1234567, .8675309, andTrailing: 8675309., positiveSign: +1, - trailingComma: "in objects", andIn: ["arrays",], + trailingComma: 'in objects', andIn: ['arrays',], escSeq: "\uAFFE", "backwardsCompatible": "with JSON", Infinity: Infinity,