From c82c6116ede2706a9d5b28d43e8271ec13be2794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 26 Apr 2022 19:32:08 +0200 Subject: [PATCH] search: regression: crash when moving viewport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5c4ddebc3c57724bd89b959a33f5ad0bd97f482b refactored search_update_selection(), specifically, the logic that moves the viewport. It did so by converting the absolute row number (of the match) to scrollback relative coordinates. This way we could ensure the viewport wasn’t moved “too much” (e.g. beyond the scrollback start). However, grid_row_abs_to_sb() and grid_row_sb_to_abs() doesn’t take a partially filled scrollback into account. This means the row (numbers) it returns may refer to *uninitialized* rows. Since: * The match row itself is valid (we *know* it has text on it) * We *subtract* from it, when setting the new viewport (to center the match on the screen). it’s only the *upper* part of the new viewport that may be uninitialized. I.e. we may have adjusted it too much. So, what we need to do is move the viewport forward until its *first* row is initialized. Then we know the rest will be too. --- search.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/search.c b/search.c index 72c589f2..8f2315a0 100644 --- a/search.c +++ b/search.c @@ -209,6 +209,13 @@ search_update_selection(struct terminal *term, const struct range *match) const int old_view = grid->view; int new_view = grid_row_sb_to_abs(grid, term->rows, rebased_new_view); + /* Scrollback may not be completely filled yet */ + { + const int mask = grid->num_rows - 1; + while (grid->rows[new_view] == NULL) + new_view = (new_view + 1) & mask; + } + #if defined(_DEBUG) /* Verify all to-be-visible rows have been allocated */ for (int r = 0; r < term->rows; r++)