From 96ff66b2259d28d7761dabc5bb01cfb32e2ef05c Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Mon, 24 Apr 2023 18:26:55 -0700 Subject: [PATCH] Fix infinite loop in running macro to EOF To test fix, try making file ``` f f ``` and recording macro of find/replace form searching for f, then running until EOF. This does not break any existing behavior, including: - macros where the cursor moves towards EOF but line num doesn't change (those already stopped after one iteration) - macros where line(s) are deleted with every iteration (even if line number doesn't change, they run until file empty) - macros where the line number increases with each iteration - macros where the cursor advances up or down with each iteration but would eventually stop anyway (those end at the correct time) Fix #13342, close #13587 --- PowerEditor/src/NppBigSwitch.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index 8320b54eb..86ad6fdbc 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -1471,6 +1471,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa int indexMacro = _runMacroDlg.getMacro2Exec(); intptr_t deltaLastLine = 0; intptr_t deltaCurrLine = 0; + bool cursorMovedUp = false; Macro m = _macro; @@ -1492,7 +1493,14 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa } else // run until eof { - bool cursorMovedUp = deltaCurrLine < 0; + if (counter > 2 && cursorMovedUp != (deltaCurrLine < 0) && deltaLastLine >= 0) + { + // the current line must be monotonically increasing or monotonically + // decreasing. Otherwise we don't know that the loop will end, + // unless the number of lines is decreasing with every iteration. + break; + } + cursorMovedUp = deltaCurrLine < 0; deltaLastLine = _pEditView->execute(SCI_GETLINECOUNT) - 1 - lastLine; deltaCurrLine = _pEditView->getCurrentLineNumber() - currLine;