From 9bd14c0fd217721d32f52808878ed7e89bb82a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 8 May 2021 19:02:33 +0200 Subject: [PATCH 1/3] sixel: fix assertion: image is allowed to cover the entire scrollback --- sixel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sixel.c b/sixel.c index 0e8c58d5..910e4a5f 100644 --- a/sixel.c +++ b/sixel.c @@ -799,7 +799,7 @@ sixel_unhook(struct terminal *term) .opaque = !term->sixel.transparent_bg, }; - xassert(image.rows < term->grid->num_rows); + xassert(image.rows <= term->grid->num_rows); xassert(image.pos.row + image.rows - 1 < term->grid->num_rows); LOG_DBG("generating %dx%d pixman image at %d-%d", From ba451af5c73ae4198b354690f2f2321364367d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 8 May 2021 19:03:08 +0200 Subject: [PATCH 2/3] =?UTF-8?q?sixel:=20don=E2=80=99t=20emit=20sixels=20th?= =?UTF-8?q?at=20will=20end=20up=20covering=20more=20than=20the=20entire=20?= =?UTF-8?q?scrollback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This limit can be reached by the sixel alone, or the sixel + the final newline. Closes #494 --- sixel.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/sixel.c b/sixel.c index 910e4a5f..5840e887 100644 --- a/sixel.c +++ b/sixel.c @@ -761,14 +761,28 @@ sixel_unhook(struct terminal *term) int start_row = do_scroll ? term->grid->cursor.point.row : 0; const int start_col = do_scroll ? term->grid->cursor.point.col : 0; - if (pixel_rows_left == 0 || rows_avail == 0) { + /* Total number of rows needed by image (+ optional newline at the end) */ + const int rows_needed = + (term->sixel.image.height + term->cell_height - 1) / term->cell_height + + (term->sixel.cursor_right_of_graphics ? 0 : 1); + + /* Will we be emitting anything at all? */ + const bool no_emission = + rows_needed > term->grid->num_rows || + pixel_rows_left == 0 || + rows_avail == 0; + + if (no_emission) { /* We won’t be emitting any sixels - free backing image */ free(term->sixel.image.data); } /* We do not allow sixels to cross the scrollback wrap-around, as * this makes intersection calculations much more complicated */ - while (pixel_rows_left > 0 && rows_avail > 0) { + while (pixel_rows_left > 0 && + rows_avail > 0 && + rows_needed <= term->grid->num_rows) + { const int cur_row = (term->grid->offset + start_row) & (term->grid->num_rows - 1); const int rows_left_until_wrap_around = term->grid->num_rows - cur_row; const int usable_rows = min(rows_avail, rows_left_until_wrap_around); From aada44bc7e2cfebb1ce73c3b5e5777640dda5de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 8 May 2021 20:29:35 +0200 Subject: [PATCH 3/3] changelog: sixel assertion hit when a sixel fills the scrollback --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5a37d82..d75ee569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,8 @@ * Memory leak triggered by “opening” an OSC-8 URI and then resetting the terminal without closing the URI (https://codeberg.org/dnkl/foot/issues/495). +* Assertion when emitting a sixel occupying the entire scrollback + history (https://codeberg.org/dnkl/foot/issues/494). ### Security