mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-28 01:40:17 -05:00
term: scrollback-to-text: crash when trying to extract the entire scrollback
We calculated the ‘start’ row by adding the number of screen rows to
the current grid offset. This works in most cases. But not when the
offset is close to the wrap-around.
This triggered a crash when we tried to access a row number larger
than the number of available grid rows.
Fix by bounding the start row to the number of grid rows.
This unearthed a second bug, where trying to extract the scrollback
resulted in nothing getting copied.
The extraction logic did:
for (r = start; r != (end + 1); r++)
....
This works, as long as end isn’t start-1. When we try to extract the
entire scrollback, it _is_ start-1.
Fix by rewriting the loop logic to check for r==end *after* copying
the row contents, but *before* incrementing r.
Closes #926
This commit is contained in:
parent
b2d59a0e54
commit
631c63d5a4
1 changed files with 19 additions and 10 deletions
29
terminal.c
29
terminal.c
|
|
@ -3414,16 +3414,22 @@ rows_to_text(const struct terminal *term, int start, int end,
|
|||
if (ctx == NULL)
|
||||
return false;
|
||||
|
||||
for (size_t r = start;
|
||||
r != ((end + 1) & (term->grid->num_rows - 1));
|
||||
r = (r + 1) & (term->grid->num_rows - 1))
|
||||
{
|
||||
const int grid_rows = term->grid->num_rows;
|
||||
int r = start;
|
||||
|
||||
while (true) {
|
||||
const struct row *row = term->grid->rows[r];
|
||||
xassert(row != NULL);
|
||||
|
||||
for (int c = 0; c < term->cols; c++)
|
||||
if (!extract_one(term, row, &row->cells[c], c, ctx))
|
||||
goto out;
|
||||
|
||||
if (r == end)
|
||||
break;
|
||||
|
||||
r++;
|
||||
r &= grid_rows - 1;
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -3433,19 +3439,22 @@ out:
|
|||
bool
|
||||
term_scrollback_to_text(const struct terminal *term, char **text, size_t *len)
|
||||
{
|
||||
int start = term->grid->offset + term->rows;
|
||||
int end = term->grid->offset + term->rows - 1;
|
||||
const int grid_rows = term->grid->num_rows;
|
||||
int start = (term->grid->offset + term->rows) & (grid_rows - 1);
|
||||
int end = (term->grid->offset + term->rows - 1) & (grid_rows - 1);
|
||||
|
||||
xassert(start >= 0);
|
||||
xassert(start < grid_rows);
|
||||
xassert(end >= 0);
|
||||
xassert(end < grid_rows);
|
||||
|
||||
/* If scrollback isn't full yet, this may be NULL, so scan forward
|
||||
* until we find the first non-NULL row */
|
||||
while (term->grid->rows[start] == NULL) {
|
||||
start++;
|
||||
start &= term->grid->num_rows - 1;
|
||||
start &= grid_rows - 1;
|
||||
}
|
||||
|
||||
if (end < 0)
|
||||
end += term->grid->num_rows;
|
||||
|
||||
while (term->grid->rows[end] == NULL) {
|
||||
end--;
|
||||
if (end < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue