Skip to content

Commit ba8cd6a

Browse files
ozone10donho
authored andcommitted
Fix memory leak on external lexers
Use smart pointers for 'lang' containers. Fix notepad-plus-plus#17420, close notepad-plus-plus#17421
1 parent dc1375d commit ba8cd6a

10 files changed

Lines changed: 124 additions & 119 deletions

File tree

PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,14 @@ int PluginsManager::loadPluginFromPath(const wchar_t *pluginFilePath)
206206

207207
int numLexers = GetLexerCount();
208208

209-
ExternalLangContainer* containers[30]{};
209+
std::unique_ptr<ExternalLangContainer> containers[30]{};
210210

211211
for (int x = 0; x < numLexers; ++x)
212212
{
213213
GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN);
214214
if (!nppParams.isExistingExternalLangName(lexName) && nppParams.ExternalLangHasRoom())
215215
{
216-
containers[x] = new ExternalLangContainer;
216+
containers[x] = std::make_unique<ExternalLangContainer>();
217217
containers[x]->_name = lexName;
218218
containers[x]->fnCL = CreateLexer;
219219
//containers[x]->fnGLPN = GetLibraryPropertyNames;
@@ -256,7 +256,7 @@ int PluginsManager::loadPluginFromPath(const wchar_t *pluginFilePath)
256256
for (int x = 0; x < numLexers; ++x) // postpone adding in case the xml is missing/corrupt
257257
{
258258
if (containers[x] != nullptr)
259-
nppParams.addExternalLangToEnd(containers[x]);
259+
nppParams.addExternalLangToEnd(std::move(containers[x]));
260260
}
261261

262262
nppParams.getExternalLexerFromXmlTree(pXmlDoc);

PowerEditor/src/Notepad_plus.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,11 @@ LRESULT Notepad_plus::init(HWND hwnd)
524524
for (int i = 0; i < nppParam.getNbExternalLang(); ++i)
525525
{
526526
HMENU subMenu = hLangMenu;
527-
ExternalLangContainer & externalLangContainer = nppParam.getELCFromIndex(i);
527+
const ExternalLangContainer* externalLangContainer = nppParam.getELCFromIndex(i);
528528

529529
int nbItem = ::GetMenuItemCount(subMenu);
530530
wchar_t buffer[MAX_EXTERNAL_LEXER_NAME_LEN]{L'\0'};
531-
const wchar_t* lexerNameW = wmc.char2wchar(externalLangContainer._name.c_str(), CP_ACP);
531+
const wchar_t* lexerNameW = wmc.char2wchar(externalLangContainer->_name.c_str(), CP_ACP);
532532

533533
// Find the first separator which is between IDM_LANG_TEXT and languages
534534
int x = 0;
@@ -591,8 +591,8 @@ LRESULT Notepad_plus::init(HWND hwnd)
591591

592592
for (int i = 0, len = nppParam.getNbUserLang(); i < len; ++i)
593593
{
594-
UserLangContainer & userLangContainer = nppParam.getULCFromIndex(i);
595-
::InsertMenu(hLangMenu, udlpos + i, MF_BYPOSITION, IDM_LANG_USER + i + 1, userLangContainer.getName());
594+
const UserLangContainer* userLangContainer = nppParam.getULCFromIndex(i);
595+
::InsertMenu(hLangMenu, udlpos + i, MF_BYPOSITION, IDM_LANG_USER + i + 1, userLangContainer->getName());
596596
}
597597

598598
//Add recent files
@@ -2805,10 +2805,8 @@ wstring Notepad_plus::getLangDesc(LangType langType, bool getName)
28052805

28062806
if ((langType >= L_EXTERNAL) && (langType < nppParams.L_END))
28072807
{
2808-
ExternalLangContainer & elc = nppParams.getELCFromIndex(langType - L_EXTERNAL);
2809-
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
2810-
const wchar_t* lexerNameW = wmc.char2wchar(elc._name.c_str(), CP_ACP);
2811-
return wstring(lexerNameW);
2808+
const ExternalLangContainer* elc = nppParams.getELCFromIndex(langType - L_EXTERNAL);
2809+
return string2wstring(elc->_name);
28122810
}
28132811

28142812
if (langType < L_TEXT || langType > L_EXTERNAL)
@@ -3650,7 +3648,7 @@ void Notepad_plus::maintainIndentation(wchar_t ch)
36503648
if (type >= L_EXTERNAL)
36513649
{
36523650
NppParameters& nppParam = NppParameters::getInstance();
3653-
autoIndentMode = nppParam.getELCFromIndex(type - L_EXTERNAL)._autoIndentMode;
3651+
autoIndentMode = nppParam.getELCFromIndex(type - L_EXTERNAL)->_autoIndentMode;
36543652
if (autoIndentMode == ExternalLexerAutoIndentMode::Custom)
36553653
return;
36563654
}
@@ -6990,7 +6988,7 @@ void Notepad_plus::setFindReplaceFolderFilter(const wchar_t *dir, const wchar_t
69906988
if (lt == L_USER)
69916989
{
69926990
Buffer * buf = _pEditView->getCurrentBuffer();
6993-
UserLangContainer * userLangContainer = nppParam.getULCFromName(buf->getUserDefineLangName());
6991+
const UserLangContainer* userLangContainer = nppParam.getULCFromName(buf->getUserDefineLangName());
69946992
if (userLangContainer)
69956993
ext = userLangContainer->getExtention();
69966994
}

PowerEditor/src/NppBigSwitch.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3577,7 +3577,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
35773577
if (index < 0)
35783578
return FALSE;
35793579

3580-
*(reinterpret_cast<ExternalLexerAutoIndentMode*>(lParam)) = nppParam.getELCFromIndex(index)._autoIndentMode;
3580+
*(reinterpret_cast<ExternalLexerAutoIndentMode*>(lParam)) = nppParam.getELCFromIndex(index)->_autoIndentMode;
35813581
return TRUE;
35823582
}
35833583

@@ -3587,7 +3587,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
35873587
if (index < 0)
35883588
return FALSE;
35893589

3590-
nppParam.getELCFromIndex(index)._autoIndentMode = static_cast<ExternalLexerAutoIndentMode>(lParam);
3590+
nppParam.getELCFromIndex(index)->_autoIndentMode = static_cast<ExternalLexerAutoIndentMode>(lParam);
35913591
return TRUE;
35923592
}
35933593

PowerEditor/src/NppIO.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,17 +1061,16 @@ int Notepad_plus::setFileOpenSaveDlgFilters(CustomFileDialog & fDlg, bool showAl
10611061
l = (NppParameters::getInstance()).getLangFromIndex(i++);
10621062
}
10631063

1064-
LangType lt = (LangType)langType;
1064+
const auto lt = static_cast<LangType>(langType);
10651065
wstring fileUdlString(getLangDesc(lt, true));
10661066

1067-
for (size_t u=0; u<(size_t)nppParam.getNbUserLang(); u++)
1067+
for (size_t u = 0; u < static_cast<size_t>(nppParam.getNbUserLang()); ++u)
10681068
{
1069-
UserLangContainer& ulc = nppParam.getULCFromIndex(u);
1070-
const wchar_t *extList = ulc.getExtention();
1071-
const wchar_t *lName = ulc.getName();
1069+
const UserLangContainer* ulc = nppParam.getULCFromIndex(u);
1070+
const wchar_t* extList = ulc->getExtention();
1071+
const wchar_t* lName = ulc->getName();
10721072

1073-
wstring list(L"");
1074-
list += extList;
1073+
std::wstring list = extList;
10751074

10761075
wstring stringFilters = exts2Filters(list, showAllExt ? -1 : 40);
10771076
const wchar_t *filters = stringFilters.c_str();

PowerEditor/src/Parameters.cpp

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
#include <ctime>
3131
#include <cwchar>
3232
#include <exception>
33+
#include <locale>
3334
#include <map>
35+
#include <memory>
3436
#include <sstream>
3537
#include <stdexcept>
3638
#include <string>
@@ -714,9 +716,11 @@ void cutString(const wchar_t* str2cut, vector<std::wstring>& patternVect)
714716
const wchar_t *pBegin = str2cut;
715717
const wchar_t *pEnd = pBegin;
716718

719+
static const auto& loc = std::locale::classic();
720+
717721
while (*pEnd != '\0')
718722
{
719-
if (_istspace(*pEnd))
723+
if (std::isspace(*pEnd, loc))
720724
{
721725
if (pBegin != pEnd)
722726
patternVect.emplace_back(pBegin, pEnd);
@@ -923,7 +927,7 @@ bool DynamicMenu::createMenu() const
923927
::InsertMenu(_hMenu, static_cast<UINT>(_posBase + i), flag, item._cmdID, item._itemName.c_str());
924928
lastIsSep = false;
925929
}
926-
else if (item._cmdID == 0 && !lastIsSep)
930+
else if (!lastIsSep)
927931
{
928932
::InsertMenu(_hMenu, static_cast<UINT>(_posBase + i), flag, item._cmdID, item._itemName.c_str());
929933
lastIsSep = true;
@@ -1088,13 +1092,6 @@ NppParameters::NppParameters()
10881092

10891093
NppParameters::~NppParameters()
10901094
{
1091-
for (int i = 0 ; i < _nbLang ; ++i)
1092-
delete _langList[i];
1093-
for (int i = 0 ; i < _nbRecentFile ; ++i)
1094-
delete _LRFileList[i];
1095-
for (int i = 0 ; i < _nbUserLang ; ++i)
1096-
delete _userLangArray[i];
1097-
10981095
for (std::vector<TiXmlDocument *>::iterator it = _pXmlExternalLexerDoc.begin(), end = _pXmlExternalLexerDoc.end(); it != end; ++it )
10991096
delete (*it);
11001097

@@ -1880,12 +1877,12 @@ int NppParameters::getExternalLangIndexFromName(const wchar_t* externalLangName)
18801877
}
18811878

18821879

1883-
UserLangContainer* NppParameters::getULCFromName(const wchar_t *userLangName)
1880+
const UserLangContainer* NppParameters::getULCFromName(const wchar_t* userLangName) const
18841881
{
18851882
for (int i = 0 ; i < _nbUserLang ; ++i)
18861883
{
18871884
if (lstrcmp(userLangName, _userLangArray[i]->_name.c_str()) == 0)
1888-
return _userLangArray[i];
1885+
return _userLangArray[i].get();
18891886
}
18901887

18911888
//qui doit etre jamais passer
@@ -1983,12 +1980,12 @@ void NppParameters::getExternalLexerFromXmlTree(TiXmlDocument* externalLexerDoc)
19831980
}
19841981

19851982

1986-
int NppParameters::addExternalLangToEnd(ExternalLangContainer * externalLang)
1983+
int NppParameters::addExternalLangToEnd(std::unique_ptr<ExternalLangContainer> externalLang)
19871984
{
1988-
_externalLangArray[_nbExternalLang] = externalLang;
1985+
_externalLangArray[_nbExternalLang] = std::move(externalLang);
19891986
++_nbExternalLang;
19901987
++L_END;
1991-
return _nbExternalLang-1;
1988+
return _nbExternalLang - 1;
19921989
}
19931990

19941991

@@ -2250,10 +2247,11 @@ void NppParameters::updateLangXml(TiXmlElement* mainElemUser, TiXmlElement* main
22502247
std::sort(vwsUserWords.begin(), vwsUserWords.end());
22512248

22522249
// convert that list into space-separated string, with at most 8000 characters per line
2253-
size_t lineLength = 0, maxLineLength = 8000;
2250+
size_t lineLength = 0;
2251+
static constexpr size_t maxLineLength = 8000;
22542252
bool first = true;
2255-
std::wstring wsOutputWords(L"");
2256-
for (auto wsWord : vwsUserWords)
2253+
std::wstring wsOutputWords;
2254+
for (const auto& wsWord : vwsUserWords)
22572255
{
22582256
if (!first)
22592257
{
@@ -3270,7 +3268,7 @@ void NppParameters::feedFileListParameters(TiXmlNode *node)
32703268
const wchar_t *filePath = (childNode->ToElement())->Attribute(L"filename");
32713269
if (filePath)
32723270
{
3273-
_LRFileList[_nbRecentFile] = new std::wstring(filePath);
3271+
_LRFileList[_nbRecentFile] = std::make_unique<std::wstring>(filePath);
32743272
++_nbRecentFile;
32753273
}
32763274
}
@@ -3881,7 +3879,7 @@ std::pair<unsigned char, unsigned char> NppParameters::feedUserLang(TiXmlNode *n
38813879
}
38823880

38833881
try {
3884-
_userLangArray[_nbUserLang] = new UserLangContainer(name, ext, isDarkModeTheme, udlVersion ? udlVersion : L"");
3882+
_userLangArray[_nbUserLang] = std::make_unique<UserLangContainer>(name, ext, isDarkModeTheme, udlVersion ? udlVersion : L"");
38853883

38863884
++_nbUserLang;
38873885

@@ -3914,7 +3912,7 @@ std::pair<unsigned char, unsigned char> NppParameters::feedUserLang(TiXmlNode *n
39143912
}
39153913
catch (const std::exception&)
39163914
{
3917-
delete _userLangArray[--_nbUserLang];
3915+
_userLangArray[--_nbUserLang].reset();
39183916
}
39193917
}
39203918
int iEnd = _nbUserLang;
@@ -3953,7 +3951,7 @@ bool NppParameters::exportUDLToFile(size_t langIndex2export, const std::wstring&
39533951
TiXmlDocument *pNewXmlUserLangDoc = new TiXmlDocument(fileName2save);
39543952
TiXmlNode *newRoot2export = pNewXmlUserLangDoc->InsertEndChild(TiXmlElement(L"NotepadPlus"));
39553953

3956-
insertUserLang2Tree(newRoot2export, _userLangArray[langIndex2export]);
3954+
insertUserLang2Tree(newRoot2export, _userLangArray[langIndex2export].get());
39573955
bool result = pNewXmlUserLangDoc->SaveFile();
39583956

39593957
delete pNewXmlUserLangDoc;
@@ -4153,7 +4151,7 @@ void NppParameters::writeDefaultUDL()
41534151

41544152
for (int i = udl._indexRange.first; i < udl._indexRange.second; ++i)
41554153
{
4156-
insertUserLang2Tree(root, _userLangArray[i]);
4154+
insertUserLang2Tree(root, _userLangArray[i].get());
41574155
}
41584156
}
41594157
}
@@ -4211,7 +4209,7 @@ void NppParameters::writeNonDefaultUDL()
42114209

42124210
for (int i = udl._indexRange.first; i < udl._indexRange.second; ++i)
42134211
{
4214-
insertUserLang2Tree(root, _userLangArray[i]);
4212+
insertUserLang2Tree(root, _userLangArray[i].get());
42154213
}
42164214
udl._udlXmlDoc->SaveFile();
42174215
}
@@ -4351,8 +4349,8 @@ void NppParameters::writeSession(const Session & session, const wchar_t *fileNam
43514349
BOOL doesBackupCopyExist = FALSE;
43524350
if (doesFileExist(sessionPathName))
43534351
{
4354-
_tcscpy(backupPathName, sessionPathName);
4355-
_tcscat(backupPathName, SESSION_BACKUP_EXT);
4352+
std::wcscpy(backupPathName, sessionPathName);
4353+
std::wcscat(backupPathName, SESSION_BACKUP_EXT);
43564354

43574355
// Make sure backup file is not read-only, if it exists
43584356
removeReadOnlyFlagFromFileAttributes(backupPathName);
@@ -4628,13 +4626,12 @@ void NppParameters::writeShortcuts()
46284626
}
46294627

46304628

4631-
int NppParameters::addUserLangToEnd(const UserLangContainer & userLang, const wchar_t *newName)
4629+
int NppParameters::addUserLangToEnd(const UserLangContainer* userLang, const wchar_t *newName)
46324630
{
46334631
if (isExistingUserLangName(newName))
46344632
return -1;
46354633
unsigned char iBegin = _nbUserLang;
4636-
_userLangArray[_nbUserLang] = new UserLangContainer();
4637-
*(_userLangArray[_nbUserLang]) = userLang;
4634+
_userLangArray[_nbUserLang] = std::make_unique<UserLangContainer>(*userLang);
46384635
_userLangArray[_nbUserLang]->_name = newName;
46394636
++_nbUserLang;
46404637
unsigned char iEnd = _nbUserLang;
@@ -4650,13 +4647,13 @@ int NppParameters::addUserLangToEnd(const UserLangContainer & userLang, const wc
46504647

46514648
void NppParameters::removeUserLang(size_t index)
46524649
{
4653-
if (static_cast<int32_t>(index) >= _nbUserLang)
4650+
if (index >= _nbUserLang)
46544651
return;
4655-
delete _userLangArray[index];
4652+
_userLangArray[index].reset();
46564653

4657-
for (int32_t i = static_cast<int32_t>(index); i < (_nbUserLang - 1); ++i)
4658-
_userLangArray[i] = _userLangArray[i+1];
4659-
_nbUserLang--;
4654+
for (size_t i = index; i < (size_t{ _nbUserLang } - 1); ++i)
4655+
_userLangArray[i] = std::move(_userLangArray[i + 1]);
4656+
--_nbUserLang;
46604657

46614658
removeIndexFromXmlUdls(index);
46624659
}
@@ -5526,7 +5523,7 @@ void NppParameters::feedKeyWordsParameters(TiXmlNode* node)
55265523
const wchar_t* name = element->Attribute(L"name");
55275524
if (name)
55285525
{
5529-
_langList[_nbLang] = new Lang(getLangIDFromStr(name), name);
5526+
_langList[_nbLang] = std::make_unique<Lang>(getLangIDFromStr(name), name);
55305527
_langList[_nbLang]->setDefaultExtList(element->Attribute(L"ext"));
55315528
_langList[_nbLang]->setCommentLineSymbol(element->Attribute(L"commentLine"));
55325529
_langList[_nbLang]->setCommentStart(element->Attribute(L"commentStart"));
@@ -5558,10 +5555,6 @@ void NppParameters::feedKeyWordsParameters(TiXmlNode* node)
55585555
}
55595556
}
55605557

5561-
extern "C" {
5562-
typedef DWORD (WINAPI * EESFUNC) (LPCTSTR, LPTSTR, DWORD);
5563-
}
5564-
55655558
void NppParameters::feedGUIParameters(TiXmlNode *node)
55665559
{
55675560
TiXmlNode *GUIRoot = node->FirstChildElement(L"GUIConfigs");
@@ -9001,9 +8994,9 @@ TiXmlElement * NppParameters::insertGUIConfigBoolNode(TiXmlNode *r2w, const wcha
90018994
return GUIConfigElement;
90028995
}
90038996

9004-
int RGB2int(COLORREF color)
8997+
static int RGB2int(COLORREF color)
90058998
{
9006-
return (((((DWORD)color) & 0x0000FF) << 16) | ((((DWORD)color) & 0x00FF00)) | ((((DWORD)color) & 0xFF0000) >> 16));
8999+
return (((color & 0x0000FF) << 16) | ((color & 0x00FF00)) | ((color & 0xFF0000) >> 16));
90079000
}
90089001

90099002
int NppParameters::langTypeToCommandID(LangType lt) const
@@ -9495,7 +9488,7 @@ void NppParameters::writeStyle2Element(const Style & style2Write, Style & style2
94959488

94969489
}
94979490

9498-
void NppParameters::insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang)
9491+
void NppParameters::insertUserLang2Tree(TiXmlNode* node, const UserLangContainer* userLang)
94999492
{
95009493
TiXmlElement *rootElement = (node->InsertEndChild(TiXmlElement(L"UserLang")))->ToElement();
95019494

@@ -9749,7 +9742,7 @@ Date::Date(const wchar_t *dateStr)
97499742
// if the value of nbDaysFromNow is 0 then the date will be now
97509743
Date::Date(int nbDaysFromNow)
97519744
{
9752-
const time_t oneDay = (60 * 60 * 24);
9745+
static constexpr time_t oneDay = (60 * 60 * 24);
97539746

97549747
time_t rawtime;
97559748
const tm* timeinfo;

0 commit comments

Comments
 (0)