Refactoring: use dynamic allocation to reduce stackoverflow risk

ref: https://github.com/notepad-plus-plus/notepad-plus-plus/issues/16865#issuecomment-3120357091

Close #16871
This commit is contained in:
Don Ho 2025-07-26 17:15:01 +02:00
parent 71fbdae005
commit 36aeb8f681
3 changed files with 73 additions and 46 deletions

View File

@ -511,9 +511,11 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
const NppGUI& nppGui = nppParam.getNppGUI();
if (nppGui._fillFindFieldWithSelected)
{
wchar_t str[strSize]{};
_pEditView->getGenericSelectedText(str, strSize, nppGui._fillFindFieldSelectCaret);
_findReplaceDlg.setSearchText(str);
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
_pEditView->getGenericSelectedText(str.get(), strSize, nppGui._fillFindFieldSelectCaret);
_findReplaceDlg.setSearchText(str.get());
}
if (isFirstTime)
@ -527,13 +529,14 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
case NPPM_INTERNAL_FINDINPROJECTS:
{
constexpr int strSize = FINDREPLACE_MAXLENGTH;
wchar_t str[strSize]{};
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
bool isFirstTime = not _findReplaceDlg.isCreated();
_findReplaceDlg.doDialog(FIND_DLG, _nativeLangSpeaker.isRTL());
_pEditView->getGenericSelectedText(str, strSize);
_findReplaceDlg.setSearchText(str);
_pEditView->getGenericSelectedText(str.get(), strSize);
_findReplaceDlg.setSearchText(str.get());
if (isFirstTime)
_nativeLangSpeaker.changeDlgLang(_findReplaceDlg.getHSelf(), "Find");
_findReplaceDlg.launchFindInProjectsDlg();
@ -544,15 +547,17 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
case NPPM_INTERNAL_FINDINFINDERDLG:
{
constexpr int strSize = FINDREPLACE_MAXLENGTH;
wchar_t str[strSize]{};
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
Finder *launcher = reinterpret_cast<Finder *>(wParam);
bool isFirstTime = !_findInFinderDlg.isCreated();
_findInFinderDlg.doDialog(launcher, _nativeLangSpeaker.isRTL());
_pEditView->getGenericSelectedText(str, strSize);
_findReplaceDlg.setSearchText(str);
_pEditView->getGenericSelectedText(str.get(), strSize);
_findReplaceDlg.setSearchText(str.get());
setFindReplaceFolderFilter(NULL, NULL);
if (isFirstTime)

View File

@ -1343,12 +1343,13 @@ void Notepad_plus::command(int id)
case IDM_SEARCH_MARK :
{
const int strSize = FINDREPLACE_MAXLENGTH;
wchar_t str[strSize] = { '\0' };
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
const NppGUI& nppGui = (NppParameters::getInstance()).getNppGUI();
if (nppGui._fillFindFieldWithSelected)
{
_pEditView->getGenericSelectedText(str, strSize, nppGui._fillFindFieldSelectCaret);
_pEditView->getGenericSelectedText(str.get(), strSize, nppGui._fillFindFieldSelectCaret);
}
bool isFirstTime = !_findReplaceDlg.isCreated();
@ -1362,9 +1363,9 @@ void Notepad_plus::command(int id)
if (nppGui._fillFindFieldWithSelected)
{
if (lstrlen(str) <= FINDREPLACE_INSELECTION_THRESHOLD_DEFAULT)
if (lstrlen(str.get()) <= FINDREPLACE_INSELECTION_THRESHOLD_DEFAULT)
{
_findReplaceDlg.setSearchText(str);
_findReplaceDlg.setSearchText(str.get());
}
}
@ -1384,7 +1385,8 @@ void Notepad_plus::command(int id)
case IDM_SEARCH_FINDINCREMENT :
{
const int strSize = FINDREPLACE_MAXLENGTH;
wchar_t str[strSize] = { '\0' };
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
static bool isFirstTime = true;
if (isFirstTime)
@ -1393,9 +1395,9 @@ void Notepad_plus::command(int id)
isFirstTime = false;
}
_pEditView->getGenericSelectedText(str, strSize, false);
_pEditView->getGenericSelectedText(str.get(), strSize, false);
if (0 != str[0]) // the selected text is not empty, then use it
_incrementFindDlg.setSearchText(str, _pEditView->getCurrentBuffer()->getUnicodeMode() != uni8Bit);
_incrementFindDlg.setSearchText(str.get(), _pEditView->getCurrentBuffer()->getUnicodeMode() != uni8Bit);
_incrementFindDlg.display();
}
@ -1444,10 +1446,12 @@ void Notepad_plus::command(int id)
_findReplaceDlg.doDialog(FIND_DLG, _nativeLangSpeaker.isRTL(), false);
const int strSize = FINDREPLACE_MAXLENGTH;
wchar_t str[strSize] = { '\0' };
_pEditView->getGenericSelectedText(str, strSize);
_findReplaceDlg.setSearchText(str);
_findReplaceDlg._env->_str2Search = str;
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
_pEditView->getGenericSelectedText(str.get(), strSize);
_findReplaceDlg.setSearchText(str.get());
_findReplaceDlg._env->_str2Search = str.get();
setFindReplaceFolderFilter(NULL, NULL);
if (isFirstTime)
_nativeLangSpeaker.changeFindReplaceDlgLang(_findReplaceDlg);
@ -1457,7 +1461,7 @@ void Notepad_plus::command(int id)
op._whichDirection = (id == IDM_SEARCH_SETANDFINDNEXT?DIR_DOWN:DIR_UP);
FindStatus status = FSNoMessage;
_findReplaceDlg.processFindNext(str, &op, &status);
_findReplaceDlg.processFindNext(str.get(), &op, &status);
if (status == FSEndReached)
{
wstring msg = _nativeLangSpeaker.getLocalizedStrFromID("find-status-end-reached", FIND_STATUS_END_REACHED_TEXT);
@ -1497,8 +1501,9 @@ void Notepad_plus::command(int id)
case IDM_SEARCH_VOLATILE_FINDPREV :
{
const int strSize = FINDREPLACE_MAXLENGTH;
wchar_t str[strSize] = { '\0' };
_pEditView->getGenericSelectedText(str, strSize);
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
_pEditView->getGenericSelectedText(str.get(), strSize);
FindOption op;
op._isMatchCase = false;
@ -1508,7 +1513,7 @@ void Notepad_plus::command(int id)
op._whichDirection = (id == IDM_SEARCH_VOLATILE_FINDNEXT ? DIR_DOWN : DIR_UP);
FindStatus status = FSNoMessage;
_findReplaceDlg.processFindNext(str, &op, &status);
_findReplaceDlg.processFindNext(str.get(), &op, &status);
if (status == FSEndReached)
{
wstring msg = _nativeLangSpeaker.getLocalizedStrFromID("find-status-end-reached", FIND_STATUS_END_REACHED_TEXT);
@ -1541,22 +1546,25 @@ void Notepad_plus::command(int id)
styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT5;
const int strSize = FINDREPLACE_MAXLENGTH;
wchar_t selectedText[strSize] = { '\0' };
wchar_t wordOnCaret[strSize] = { '\0' };
auto selectedText = std::make_unique<wchar_t[]>(strSize);
std::fill_n(selectedText.get(), strSize, L'\0');
_pEditView->getGenericSelectedText(selectedText, strSize, false);
_pEditView->getGenericWordOnCaretPos(wordOnCaret, strSize);
auto wordOnCaret = std::make_unique<wchar_t[]>(strSize);
std::fill_n(wordOnCaret.get(), strSize, L'\0');
_pEditView->getGenericSelectedText(selectedText.get(), strSize, false);
_pEditView->getGenericWordOnCaretPos(wordOnCaret.get(), strSize);
if (selectedText[0] == '\0')
{
if (lstrlen(wordOnCaret) > 0)
if (lstrlen(wordOnCaret.get()) > 0)
{
_findReplaceDlg.markAll(wordOnCaret, styleID);
_findReplaceDlg.markAll(wordOnCaret.get(), styleID);
}
}
else
{
_findReplaceDlg.markAll(selectedText, styleID);
_findReplaceDlg.markAll(selectedText.get(), styleID);
}
}
break;

View File

@ -49,15 +49,21 @@ void addText2Combo(const wchar_t * txt2add, HWND hCombo)
wstring getTextFromCombo(HWND hCombo)
{
wchar_t str[FINDREPLACE_MAXLENGTH] = { '\0' };
::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str));
return wstring(str);
const int strSize = FINDREPLACE_MAXLENGTH;
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str.get()));
return wstring(str.get());
}
void delLeftWordInEdit(HWND hEdit)
{
wchar_t str[FINDREPLACE_MAXLENGTH] = { '\0' };
::SendMessage(hEdit, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str));
const int strSize = FINDREPLACE_MAXLENGTH;
auto str = std::make_unique<wchar_t[]>(strSize);
std::fill_n(str.get(), strSize, L'\0');
::SendMessage(hEdit, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str.get()));
WORD cursor = 0;
::SendMessage(hEdit, EM_GETSEL, (WPARAM)&cursor, 0);
WORD wordstart = cursor;
@ -491,7 +497,10 @@ void FindReplaceDlg::saveFindHistory()
int FindReplaceDlg::saveComboHistory(int id, int maxcount, vector<wstring> & strings, bool saveEmpty)
{
wchar_t text[FINDREPLACE_MAXLENGTH] = { '\0' };
const int strSize = FINDREPLACE_MAXLENGTH;
auto text = std::make_unique<wchar_t[]>(strSize);
std::fill_n(text.get(), strSize, L'\0');
HWND hCombo = ::GetDlgItem(_hSelf, id);
int count = static_cast<int32_t>(::SendMessage(hCombo, CB_GETCOUNT, 0, 0));
count = std::min<int>(count, maxcount);
@ -513,8 +522,8 @@ int FindReplaceDlg::saveComboHistory(int id, int maxcount, vector<wstring> & str
auto cbTextLen = ::SendMessage(hCombo, CB_GETLBTEXTLEN, i, 0);
if (cbTextLen <= FINDREPLACE_MAXLENGTH2SAVE - 1)
{
::SendMessage(hCombo, CB_GETLBTEXT, i, reinterpret_cast<LPARAM>(text));
strings.push_back(wstring(text));
::SendMessage(hCombo, CB_GETLBTEXT, i, reinterpret_cast<LPARAM>(text.get()));
strings.push_back(wstring(text.get()));
}
}
return count;
@ -4857,7 +4866,9 @@ LRESULT FAR PASCAL FindReplaceDlg::comboEditProc(HWND hwnd, UINT message, WPARAM
bool isDropped = ::SendMessage(hwndCombo, CB_GETDROPPEDSTATE, 0, 0) != 0;
static wchar_t draftString[FINDREPLACE_MAXLENGTH]{};
const size_t strSize = FINDREPLACE_MAXLENGTH;
auto draftString = std::make_unique<wchar_t[]>(strSize);
std::fill_n(draftString.get(), strSize, L'\0');
if (isDropped && (message == WM_KEYDOWN) && (wParam == VK_DELETE))
{
@ -4891,7 +4902,7 @@ LRESULT FAR PASCAL FindReplaceDlg::comboEditProc(HWND hwnd, UINT message, WPARAM
else if ((message == WM_KEYDOWN) && (wParam == VK_DOWN) && (::SendMessage(hwndCombo, CB_GETCURSEL, 0, 0) == CB_ERR))
{
// down key on unselected combobox item -> store current edit text as draft
::SendMessage(hwndCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(draftString));
::SendMessage(hwndCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(draftString.get()));
}
else if ((message == WM_KEYDOWN) && (wParam == VK_UP) && (::SendMessage(hwndCombo, CB_GETCURSEL, 0, 0) == CB_ERR))
{
@ -4899,11 +4910,11 @@ LRESULT FAR PASCAL FindReplaceDlg::comboEditProc(HWND hwnd, UINT message, WPARAM
::SendMessage(hwndCombo, CB_SETEDITSEL, 0, MAKELPARAM(0, -1));
return 0;
}
else if ((message == WM_KEYDOWN) && (wParam == VK_UP) && (::SendMessage(hwndCombo, CB_GETCURSEL, 0, 0) == 0) && std::wcslen(draftString) > 0)
else if ((message == WM_KEYDOWN) && (wParam == VK_UP) && (::SendMessage(hwndCombo, CB_GETCURSEL, 0, 0) == 0) && std::wcslen(draftString.get()) > 0)
{
// up key on top selected combobox item -> restore draft to edit text
::SendMessage(hwndCombo, CB_SETCURSEL, WPARAM(-1), 0);
::SendMessage(hwndCombo, WM_SETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(draftString));
::SendMessage(hwndCombo, WM_SETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(draftString.get()));
::SendMessage(hwndCombo, CB_SETEDITSEL, 0, MAKELPARAM(0, -1));
return 0;
@ -6225,9 +6236,12 @@ void FindIncrementDlg::markSelectedTextInc(bool enable, FindOption *opt)
if (range.cpMin == range.cpMax)
return;
wchar_t text2Find[FINDREPLACE_MAXLENGTH]{};
(*(_pFRDlg->_ppEditView))->getGenericSelectedText(text2Find, FINDREPLACE_MAXLENGTH, false); //do not expand selection (false)
opt->_str2Search = text2Find;
const int strSize = FINDREPLACE_MAXLENGTH;
auto text2Find = std::make_unique<wchar_t[]>(strSize);
std::fill_n(text2Find.get(), strSize, L'\0');
(*(_pFRDlg->_ppEditView))->getGenericSelectedText(text2Find.get(), FINDREPLACE_MAXLENGTH, false); //do not expand selection (false)
opt->_str2Search = text2Find.get();
_pFRDlg->markAllInc(opt);
}