mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
sixel: fix crash when splitting up an image across the scrollback
If an image was split up across the scrollback, and the first image chunk was resized due to it being blended with an already existing sixel, we crashed. The reason being the second chunk, emitted *after* the scrollback, tried to memcpy() image data from a now-free:d image buffer. The fix is pretty simple: create copies for *all* chunks when an image has to be split up across the scrollback. Previously, the first chunk re-used the source image buffer. Closes #608
This commit is contained in:
parent
ba26d63829
commit
a52d867947
1 changed files with 10 additions and 12 deletions
22
sixel.c
22
sixel.c
|
|
@ -964,16 +964,7 @@ sixel_unhook(struct terminal *term)
|
|||
(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);
|
||||
}
|
||||
bool free_image_data = true;
|
||||
|
||||
/* We do not allow sixels to cross the scrollback wrap-around, as
|
||||
* this makes intersection calculations much more complicated */
|
||||
|
|
@ -991,9 +982,13 @@ sixel_unhook(struct terminal *term)
|
|||
const int height = min(pixel_rows_left, pixel_rows_avail);
|
||||
|
||||
uint32_t *img_data;
|
||||
if (pixel_row_idx == 0)
|
||||
if (pixel_row_idx == 0 && height == pixel_rows_left) {
|
||||
/* Entire image will be emitted as a single chunk - reuse
|
||||
* the source buffer */
|
||||
img_data = term->sixel.image.data;
|
||||
else {
|
||||
free_image_data = false;
|
||||
} else {
|
||||
xassert(free_image_data);
|
||||
img_data = xmalloc(height * stride);
|
||||
memcpy(
|
||||
img_data,
|
||||
|
|
@ -1080,6 +1075,9 @@ sixel_unhook(struct terminal *term)
|
|||
start_row -= image.rows;
|
||||
}
|
||||
|
||||
if (free_image_data)
|
||||
free(term->sixel.image.data);
|
||||
|
||||
term->sixel.image.data = NULL;
|
||||
term->sixel.image.width = 0;
|
||||
term->sixel.image.height = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue