From 729bd57caee1cc6fd31419adf8f75ea482c37102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 15 Feb 2024 16:29:02 +0100 Subject: [PATCH] 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 --- CHANGELOG.md | 5 +++++ terminal.c | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d9d781..d3f5d119 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/terminal.c b/terminal.c index bc7dc428..d9d66bac 100644 --- a/terminal.c +++ b/terminal.c @@ -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); }