From 0e9ebf433b589c15e17bd37f73991ecc71e9b3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 26 Apr 2022 18:24:22 +0200 Subject: [PATCH] search: fix infinite loop when highlighting all matches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit find_next() did not always terminate correctly, causing search_matches_next() to never terminate, which finally leads to an infinite loop when rendering the search overlay surface, while finding all matches to highlight. The problem is that find_next(), after having found the initial matching characters, enters a nested while loop that tries to match the rest of the search criteria. This inner while loop did not check if we’ve reached the last cell, and happily continued past it (eventually wrappping around the scrollback buffer). Closes #1047 --- CHANGELOG.md | 4 +++- search.c | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb094d93..65dd2542 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,8 @@ * UI not refreshing when pasting something into the scrollback search box, that does not result in a grid update (for example, when the search criteria did not result in any matches) ([#1040][1040]). -* foot freezing in scrollback search mode, using 100% CPU ([#1036][1036]). +* foot freezing in scrollback search mode, using 100% CPU + ([#1036][1036], [#1047][1047]). * Crash when extending a selection to the next word boundary in scrollback search mode ([#1036][1036]). * Scrollback search mode not always highlighting all matches @@ -66,6 +67,7 @@ [1040]: https://codeberg.org/dnkl/foot/issues/1040 [1036]: https://codeberg.org/dnkl/foot/issues/1036 +[1047]: https://codeberg.org/dnkl/foot/issues/1036 ### Security diff --git a/search.c b/search.c index d4460e5b..b4d06c6c 100644 --- a/search.c +++ b/search.c @@ -375,6 +375,13 @@ find_next(struct terminal *term, enum search_direction direction, if (match_len != term->search.len) { /* Didn't match (completely) */ + + if (match_start_row == abs_end.row && + match_start_col == abs_end.col) + { + break; + } + continue; } @@ -563,10 +570,16 @@ search_matches_next(struct search_match_iterator *iter) xassert(match.end.row >= 0); xassert(match.end.row < term->rows); + /* Assert match end comes *after* the match start */ xassert(match.end.row > match.start.row || (match.end.row == match.start.row && match.end.col >= match.start.col)); + /* Assert the match starts at, or after, the iterator position */ + xassert(match.start.row > iter->start.row || + (match.start.row == iter->start.row && + match.start.col >= iter->start.col)); + /* Continue at next column, next time */ iter->start.row = match.start.row; iter->start.col = match.start.col + 1;