mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
term: reverse-scroll: fix crash when viewport ends up outside the (new) scrollback
If the viewport has been scrolled up, it is possible for a
reverse-scroll (rin) to cause the viewport to point to lines outside
the scrollback. This is an issue if the scrollback isn't full, since
in that case, the viewport will contain NULL lines. This will
potentially trigger assertions in a couple of different places.
Example backtrace:
#2 0x555555cd230c in bug ../../debug.c:44
#3 0x555555ad485e in grid_row_in_view ../../grid.h:83
#4 0x555555b15a89 in grid_render ../../render.c:3465
#5 0x555555b3b0ab in fdm_hook_refresh_pending_terminals ../../render.c:5165
#6 0x555555a74980 in fdm_poll ../../fdm.c:435
#7 0x555555ac2b85 in main ../../main.c:676
Detect when this happens, and force-move the viewport to ensure it is
valid.
Closes #2232
This commit is contained in:
parent
55f8388694
commit
65bd79b77d
2 changed files with 21 additions and 1 deletions
|
|
@ -96,6 +96,10 @@
|
|||
* Search mode: composing keys not ignored.
|
||||
* Crash when triple-clicking a soft-wrapped line and there is a quote
|
||||
character in the last column.
|
||||
* Crash when reverse-scrolling (terminfo capability `rin`) such that
|
||||
the current viewport ends up outside the scrollback ([#2232][2232]).
|
||||
|
||||
[2232]: https://codeberg.org/dnkl/foot/issues/2232
|
||||
|
||||
|
||||
### Security
|
||||
|
|
|
|||
18
terminal.c
18
terminal.c
|
|
@ -3165,11 +3165,17 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
|
||||
sixel_scroll_down(term, rows);
|
||||
|
||||
bool view_follows = term->grid->view == term->grid->offset;
|
||||
const bool view_follows = term->grid->view == term->grid->offset;
|
||||
term->grid->offset -= rows;
|
||||
term->grid->offset += term->grid->num_rows;
|
||||
term->grid->offset &= term->grid->num_rows - 1;
|
||||
|
||||
/* How many lines from the scrollback start is the current viewport? */
|
||||
const int view_sb_start_distance = grid_row_abs_to_sb(
|
||||
term->grid, term->rows, term->grid->view);
|
||||
const int offset_sb_start_distance = grid_row_abs_to_sb(
|
||||
term->grid, term->rows, term->grid->offset);
|
||||
|
||||
xassert(term->grid->offset >= 0);
|
||||
xassert(term->grid->offset < term->grid->num_rows);
|
||||
|
||||
|
|
@ -3177,6 +3183,11 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||
selection_view_up(term, term->grid->offset);
|
||||
term->grid->view = term->grid->offset;
|
||||
} else if (unlikely(view_sb_start_distance > offset_sb_start_distance)) {
|
||||
/* Part of current view is being scrolled out */
|
||||
int new_view = term->grid->offset;
|
||||
selection_view_up(term, new_view);
|
||||
term->grid->view = new_view;
|
||||
}
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
|
|
@ -3193,11 +3204,16 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
erase_line(term, row);
|
||||
}
|
||||
|
||||
if (unlikely(view_sb_start_distance > offset_sb_start_distance))
|
||||
term_damage_view(term);
|
||||
|
||||
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||
|
||||
#if defined(_DEBUG)
|
||||
for (int r = 0; r < term->rows; r++)
|
||||
xassert(grid_row(term->grid, r) != NULL);
|
||||
for (int r = 0; r < term->rows; r++)
|
||||
xassert(grid_row_in_view(term->grid, r) != NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue