From 6ed340c5a2bb3fdc43978fc1c8a1882d50ae2d30 Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Sun, 12 Nov 2023 01:16:23 +0300 Subject: [PATCH] Do not leak each created KviInputEditorSpellCheckerBlock Objects allocated by splitTextIntoSpellCheckerBlocks into buffer vector are never freed. Fix this by turning vector of pointers into vector of objects. --- src/kvirc/ui/KviInputEditor.cpp | 36 ++++++++++++++------------------- src/kvirc/ui/KviInputEditor.h | 8 ++++---- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/kvirc/ui/KviInputEditor.cpp b/src/kvirc/ui/KviInputEditor.cpp index 9958891e5..762f0a69c 100644 --- a/src/kvirc/ui/KviInputEditor.cpp +++ b/src/kvirc/ui/KviInputEditor.cpp @@ -350,16 +350,10 @@ bool KviInputEditor::checkWordSpelling(const QString & szWord) #define ADD_SPELLCHECKER_BLOCK(_lBuffer, _szText, _iStart, _bSpellCheckable, _bCorrect) \ do \ { \ - KviInputEditorSpellCheckerBlock * pBlock = new KviInputEditorSpellCheckerBlock(); \ - pBlock->szText = _szText; \ - pBlock->iStart = _iStart; \ - pBlock->iLength = pBlock->szText.length(); \ - pBlock->bSpellCheckable = _bSpellCheckable; \ - pBlock->bCorrect = _bCorrect; \ - _lBuffer.push_back(pBlock); \ + _lBuffer.push_back({_szText, _iStart, _szText.length(), _bSpellCheckable, _bCorrect}); \ } while(0) -void KviInputEditor::splitTextIntoSpellCheckerBlocks(const QString & szText, std::vector & lBuffer) +void KviInputEditor::splitTextIntoSpellCheckerBlocks(const QString & szText, std::vector & lBuffer) { #ifdef COMPILE_ENCHANT_SUPPORT if(szText.isEmpty()) @@ -516,7 +510,7 @@ void KviInputEditor::rebuildTextBlocks() qDeleteAll(m_p->lTextBlocks); m_p->lTextBlocks.clear(); - std::vector lSpellCheckerBlocks; + std::vector lSpellCheckerBlocks; #ifdef COMPILE_ENCHANT_SUPPORT splitTextIntoSpellCheckerBlocks(m_szTextBuffer, lSpellCheckerBlocks); @@ -542,16 +536,16 @@ void KviInputEditor::rebuildTextBlocks() KviInputEditorTextBlock * pBlock; - for(auto spb : lSpellCheckerBlocks) + for(auto& spb : lSpellCheckerBlocks) { - if(spb->bSpellCheckable && !spb->bCorrect) + if(spb.bSpellCheckable && !spb.bCorrect) uFlags |= KviInputEditorTextBlock::IsSpellingMistake; else uFlags &= ~KviInputEditorTextBlock::IsSpellingMistake; - const QChar * pBuffer = spb->szText.unicode(); + const QChar * pBuffer = spb.szText.unicode(); const QChar * p = pBuffer; - const QChar * e = p + spb->szText.length(); + const QChar * e = p + spb.szText.length(); while(p < e) { @@ -623,7 +617,7 @@ void KviInputEditor::rebuildTextBlocks() { unsigned char uFore; unsigned char uBack; - /* int iNextChar = */ KviControlCodes::getUnicodeColorBytes(spb->szText, p - spb->szText.unicode(), &uFore, &uBack); + /* int iNextChar = */ KviControlCodes::getUnicodeColorBytes(spb.szText, p - spb.szText.unicode(), &uFore, &uBack); if(uFore != KviControlCodes::NoChange) { uCurFore = uFore; @@ -1143,7 +1137,7 @@ void KviInputEditor::showContextPopup(const QPoint & pos) #ifdef COMPILE_ENCHANT_SUPPORT // check if the cursor is in a spell-checkable block - std::vector lBuffer; + std::vector lBuffer; splitTextIntoSpellCheckerBlocks(m_szTextBuffer, lBuffer); m_iSpellCheckPosition = qMin(charIndexFromXPosition(pos.x()), m_szTextBuffer.length()); @@ -1191,15 +1185,15 @@ void KviInputEditor::showContextPopupHere() showContextPopup(QPoint(fXPos, iBottom)); } -KviInputEditorSpellCheckerBlock * KviInputEditor::findSpellCheckerBlockAtCursor(std::vector & lBlocks) +KviInputEditorSpellCheckerBlock * KviInputEditor::findSpellCheckerBlockAtCursor(std::vector & lBlocks) { KviInputEditorSpellCheckerBlock * pCurrentBlock = nullptr; - for(auto pBlock : lBlocks) + for(auto& block : lBlocks) { - if(m_iSpellCheckPosition <= (pBlock->iStart + pBlock->iLength)) + if(m_iSpellCheckPosition <= (block.iStart + block.iLength)) { - pCurrentBlock = pBlock; + pCurrentBlock = █ break; } } @@ -1222,7 +1216,7 @@ void KviInputEditor::fillSpellCheckerCorrectionsPopup() #ifdef COMPILE_ENCHANT_SUPPORT // check if the cursor is in a spellcheckable block - std::vector lBuffer; + std::vector lBuffer; splitTextIntoSpellCheckerBlocks(m_szTextBuffer, lBuffer); KviInputEditorSpellCheckerBlock * pCurrentBlock = findSpellCheckerBlockAtCursor(lBuffer); @@ -1305,7 +1299,7 @@ void KviInputEditor::spellCheckerPopupCorrectionActionTriggered() if(szWord.isEmpty()) return; - std::vector lBuffer; + std::vector lBuffer; splitTextIntoSpellCheckerBlocks(m_szTextBuffer, lBuffer); KviInputEditorSpellCheckerBlock * pCurrentBlock = findSpellCheckerBlockAtCursor(lBuffer); diff --git a/src/kvirc/ui/KviInputEditor.h b/src/kvirc/ui/KviInputEditor.h index 58b92c879..ba95aed08 100644 --- a/src/kvirc/ui/KviInputEditor.h +++ b/src/kvirc/ui/KviInputEditor.h @@ -73,8 +73,8 @@ class KviInputEditorSpellCheckerBlock { public: QString szText; - int iStart; - int iLength; + qsizetype iStart; + qsizetype iLength; bool bSpellCheckable; bool bCorrect; }; @@ -975,8 +975,8 @@ private slots: QVariant inputMethodQuery(Qt::InputMethodQuery query) const override; void paintEvent(QPaintEvent * e) override; bool checkWordSpelling(const QString & szWord); - void splitTextIntoSpellCheckerBlocks(const QString & szText, std::vector & lBuffer); - KviInputEditorSpellCheckerBlock * findSpellCheckerBlockAtCursor(std::vector & lBlocks); + void splitTextIntoSpellCheckerBlocks(const QString & szText, std::vector & lBuffer); + KviInputEditorSpellCheckerBlock * findSpellCheckerBlockAtCursor(std::vector & lBlocks); void fillSpellCheckerCorrectionsPopup(); void rebuildTextBlocks();