term: erase-scrollback: handle non-existing scrollback history

If scrollback.lines == 0, and the window size (number of rows) is a
power of two, all rows are always visible. I.e. there is no scrollback
history.

This threw off the scrollback erase logic, causing visible rows to be
erased, and set to NULL. This triggered a crash when trying to update
the view.

Closes #1610
This commit is contained in:
Daniel Eklöf 2024-02-15 16:29:02 +01:00
parent c114afadbd
commit 729bd57cae
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 16 additions and 0 deletions

View file

@ -109,11 +109,16 @@
-E,--client-environment` ([#1568][1568]).
* XDG toplevel protocol violation, by trying to set a title that
contains an invalid UTF-8 sequence ([#1552][1552]).
* Crash when erasing the scrollback, when scrollback history is
exactly 0 rows. This happens when `[scrollback].line = 0`, and the
window size (number of rows) is a power of two (i.e. 2, 4, 8, 16
etc) ([#1610][1610]).
[1531]: https://codeberg.org/dnkl/foot/issues/1531
[1573]: https://codeberg.org/dnkl/foot/issues/1573
[1568]: https://codeberg.org/dnkl/foot/issues/1568
[1552]: https://codeberg.org/dnkl/foot/issues/1552
[1610]: https://codeberg.org/dnkl/foot/issues/1610
### Security

View file

@ -2350,6 +2350,10 @@ term_erase_scrollback(struct terminal *term)
const int num_rows = grid->num_rows;
const int mask = num_rows - 1;
const int scrollback_history_size = num_rows - term->rows;
if (scrollback_history_size == 0)
return;
const int start = (grid->offset + term->rows) & mask;
const int end = (grid->offset - 1) & mask;
@ -2416,6 +2420,13 @@ term_erase_scrollback(struct terminal *term)
}
term->grid->view = term->grid->offset;
#if defined(_DEBUG)
for (int i = 0; i < term->rows; i++) {
xassert(grid_row_in_view(term->grid, i) != NULL);
}
#endif
term_damage_view(term);
}