From 70cd3e5ea69b95392c88cb0fc2b9eba0f3de0c82 Mon Sep 17 00:00:00 2001 From: Don HO Date: Thu, 21 Feb 2019 20:11:42 +0100 Subject: [PATCH] [EU-FOSSA] Check if the command is macroable before playing the recorded macro Such situation can happen via the manual modification of shortcut.xml by hackers. --- .../src/WinControls/shortcut/shortcut.cpp | 136 +++++++++++++++++- .../src/WinControls/shortcut/shortcut.h | 1 + 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/PowerEditor/src/WinControls/shortcut/shortcut.cpp b/PowerEditor/src/WinControls/shortcut/shortcut.cpp index e78cb005..a8a5d8a3 100644 --- a/PowerEditor/src/WinControls/shortcut/shortcut.cpp +++ b/PowerEditor/src/WinControls/shortcut/shortcut.cpp @@ -664,14 +664,143 @@ recordedMacroStep::recordedMacroStep(int iMessage, uptr_t wParam, uptr_t lParam, } } +// code comes from Scintilla's Editor.cxx: +// void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) +bool recordedMacroStep::isMacroable(unsigned int iMessage) +{ + // Enumerates all macroable messages + switch (iMessage) + { + case SCI_CUT: + case SCI_COPY: + case SCI_PASTE: + case SCI_CLEAR: + case SCI_REPLACESEL: + case SCI_ADDTEXT: + case SCI_INSERTTEXT: + case SCI_APPENDTEXT: + case SCI_CLEARALL: + case SCI_SELECTALL: + case SCI_GOTOLINE: + case SCI_GOTOPOS: + case SCI_SEARCHANCHOR: + case SCI_SEARCHNEXT: + case SCI_SEARCHPREV: + case SCI_LINEDOWN: + case SCI_LINEDOWNEXTEND: + case SCI_PARADOWN: + case SCI_PARADOWNEXTEND: + case SCI_LINEUP: + case SCI_LINEUPEXTEND: + case SCI_PARAUP: + case SCI_PARAUPEXTEND: + case SCI_CHARLEFT: + case SCI_CHARLEFTEXTEND: + case SCI_CHARRIGHT: + case SCI_CHARRIGHTEXTEND: + case SCI_WORDLEFT: + case SCI_WORDLEFTEXTEND: + case SCI_WORDRIGHT: + case SCI_WORDRIGHTEXTEND: + case SCI_WORDPARTLEFT: + case SCI_WORDPARTLEFTEXTEND: + case SCI_WORDPARTRIGHT: + case SCI_WORDPARTRIGHTEXTEND: + case SCI_WORDLEFTEND: + case SCI_WORDLEFTENDEXTEND: + case SCI_WORDRIGHTEND: + case SCI_WORDRIGHTENDEXTEND: + case SCI_HOME: + case SCI_HOMEEXTEND: + case SCI_LINEEND: + case SCI_LINEENDEXTEND: + case SCI_HOMEWRAP: + case SCI_HOMEWRAPEXTEND: + case SCI_LINEENDWRAP: + case SCI_LINEENDWRAPEXTEND: + case SCI_DOCUMENTSTART: + case SCI_DOCUMENTSTARTEXTEND: + case SCI_DOCUMENTEND: + case SCI_DOCUMENTENDEXTEND: + case SCI_STUTTEREDPAGEUP: + case SCI_STUTTEREDPAGEUPEXTEND: + case SCI_STUTTEREDPAGEDOWN: + case SCI_STUTTEREDPAGEDOWNEXTEND: + case SCI_PAGEUP: + case SCI_PAGEUPEXTEND: + case SCI_PAGEDOWN: + case SCI_PAGEDOWNEXTEND: + case SCI_EDITTOGGLEOVERTYPE: + case SCI_CANCEL: + case SCI_DELETEBACK: + case SCI_TAB: + case SCI_BACKTAB: + case SCI_FORMFEED: + case SCI_VCHOME: + case SCI_VCHOMEEXTEND: + case SCI_VCHOMEWRAP: + case SCI_VCHOMEWRAPEXTEND: + case SCI_VCHOMEDISPLAY: + case SCI_VCHOMEDISPLAYEXTEND: + case SCI_DELWORDLEFT: + case SCI_DELWORDRIGHT: + case SCI_DELWORDRIGHTEND: + case SCI_DELLINELEFT: + case SCI_DELLINERIGHT: + case SCI_LINECOPY: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LINEDUPLICATE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: + case SCI_LINESCROLLDOWN: + case SCI_LINESCROLLUP: + case SCI_DELETEBACKNOTLINE: + case SCI_HOMEDISPLAY: + case SCI_HOMEDISPLAYEXTEND: + case SCI_LINEENDDISPLAY: + case SCI_LINEENDDISPLAYEXTEND: + case SCI_SETSELECTIONMODE: + case SCI_LINEDOWNRECTEXTEND: + case SCI_LINEUPRECTEXTEND: + case SCI_CHARLEFTRECTEXTEND: + case SCI_CHARRIGHTRECTEXTEND: + case SCI_HOMERECTEXTEND: + case SCI_VCHOMERECTEXTEND: + case SCI_LINEENDRECTEXTEND: + case SCI_PAGEUPRECTEXTEND: + case SCI_PAGEDOWNRECTEXTEND: + case SCI_SELECTIONDUPLICATE: + case SCI_COPYALLOWLINE: + case SCI_VERTICALCENTRECARET: + case SCI_MOVESELECTEDLINESUP: + case SCI_MOVESELECTEDLINESDOWN: + case SCI_SCROLLTOSTART: + case SCI_SCROLLTOEND: + return true; + + // Filter out all others like display changes. Also, newlines are redundant + // with char insert messages. + case SCI_NEWLINE: + default: + return false; + } +} + void recordedMacroStep::PlayBack(Window* pNotepad, ScintillaEditView *pEditView) { if (_macroType == mtMenuCommand) + { ::SendMessage(pNotepad->getHSelf(), WM_COMMAND, _wParameter, 0); - + } else { - if (_macroType == mtUseSParameter) + // Ensure it's macroable message before send it + if (!isMacroable(_message)) + return; + + if (_macroType == mtUseSParameter) { char ansiBuffer[3]; ::WideCharToMultiByte(static_cast(pEditView->execute(SCI_GETCODEPAGE)), 0, _sParameter.c_str(), -1, ansiBuffer, 3, NULL, NULL); @@ -683,6 +812,8 @@ void recordedMacroStep::PlayBack(Window* pNotepad, ScintillaEditView *pEditView) pEditView->execute(_message, _wParameter, _lParameter); } + // If text content has been modified in Scintilla, + // then notify Notepad++ if ( (_message == SCI_SETTEXT) || (_message == SCI_REPLACESEL) || (_message == SCI_ADDTEXT) @@ -698,6 +829,7 @@ void recordedMacroStep::PlayBack(Window* pNotepad, ScintillaEditView *pEditView) scnN.ch = 0; else scnN.ch = _sParameter.at(0); + ::SendMessage(pNotepad->getHSelf(), WM_NOTIFY, 0, reinterpret_cast(&scnN)); } } diff --git a/PowerEditor/src/WinControls/shortcut/shortcut.h b/PowerEditor/src/WinControls/shortcut/shortcut.h index 306db117..0c23075a 100644 --- a/PowerEditor/src/WinControls/shortcut/shortcut.h +++ b/PowerEditor/src/WinControls/shortcut/shortcut.h @@ -301,6 +301,7 @@ struct recordedMacroStep { return true; }; bool isPlayable() const {return _macroType <= mtMenuCommand;}; + bool isMacroable(unsigned int iMessage); void PlayBack(Window* pNotepad, ScintillaEditView *pEditView); };