search: find_next(): proper check for scrollback wrap around

Besides disallowing matches that crosses the scrollback wrap-around,
this also fixes a crash when the trying to search beyond the last
output, when the scrollback history hasn’t yet been completely filled.
This commit is contained in:
Daniel Eklöf 2021-03-28 20:59:35 +02:00
parent f87a13bbd2
commit e415f85829
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 15 additions and 5 deletions

View file

@ -153,6 +153,7 @@
* PTY not being drained when the client application terminates.
* `auto_left_margin` not being limited to `cub1`
(https://codeberg.org/dnkl/foot/issues/441).
* Crash in scrollback search mode when searching beyond the last output.
### Contributors

View file

@ -77,6 +77,16 @@ search_ensure_size(struct terminal *term, size_t wanted_size)
return true;
}
static bool
has_wrapped_around(const struct terminal *term, int abs_row_no)
{
int scrollback_start = term->grid->offset + term->rows;
int rebased_row = abs_row_no - scrollback_start + term->grid->num_rows;
rebased_row &= term->grid->num_rows - 1;
return rebased_row == 0;
}
static void
search_cancel_keep_selection(struct terminal *term)
{
@ -327,13 +337,12 @@ search_find_next(struct terminal *term)
for (size_t i = 0; i < term->search.len;) {
if (end_col >= term->cols) {
if (end_row + 1 > grid_row_absolute(term->grid, term->grid->offset + term->rows - 1)) {
/* Don't continue past end of the world */
break;
}
end_row++;
end_col = 0;
if (has_wrapped_around(term, end_row))
break;
row = term->grid->rows[end_row];
}