sixel: resize: truncate instead of failing, when new size exceeds max size

If the size we’re trying to set exceeds the configured max size,
truncate instead of failing.
This commit is contained in:
Daniel Eklöf 2022-02-03 19:20:41 +01:00
parent 8ca0eaa94c
commit 9150507209
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 21 additions and 13 deletions

View file

@ -120,6 +120,8 @@
(https://codeberg.org/dnkl/foot/issues/883).
* Bash completion giving an error when completing a list of short
options
* Sixel: large image resizes (triggered by e.g. large repeat counts in
`DECGRI`) are now truncated instead of ignored.
### Security

32
sixel.c
View file

@ -1104,7 +1104,7 @@ sixel_unhook(struct terminal *term)
render_refresh(term);
}
static bool
static void
resize_horizontally(struct terminal *term, int new_width)
{
LOG_DBG("resizing image horizontally: %dx(%d) -> %dx(%d)",
@ -1112,10 +1112,13 @@ resize_horizontally(struct terminal *term, int new_width)
new_width, term->sixel.image.height);
if (unlikely(new_width > term->sixel.max_width)) {
LOG_WARN("maximum image dimensions reached");
return false;
LOG_WARN("maximum image dimensions exceeded, truncating");
new_width = term->sixel.max_width;
}
if (unlikely(term->sixel.image.width == new_width))
return;
uint32_t *old_data = term->sixel.image.data;
const int old_width = term->sixel.image.width;
const int height = term->sixel.image.height;
@ -1145,7 +1148,6 @@ resize_horizontally(struct terminal *term, int new_width)
term->sixel.image.data = new_data;
term->sixel.image.width = new_width;
term->sixel.row_byte_ofs = term->sixel.pos.row * new_width;
return true;
}
static bool
@ -1197,11 +1199,14 @@ resize(struct terminal *term, int new_width, int new_height)
term->sixel.image.width, term->sixel.image.height,
new_width, new_height);
if (new_width > term->sixel.max_width ||
new_height > term->sixel.max_height)
{
LOG_WARN("maximum image dimensions reached");
return false;
if (unlikely(new_width > term->sixel.max_width)) {
LOG_WARN("maximum image width exceeded, truncating");
new_width = term->sixel.max_width;
}
if (unlikely(new_height > term->sixel.max_height)) {
LOG_WARN("maximum image height exceeded, truncating");
new_height = term->sixel.max_height;
}
uint32_t *old_data = term->sixel.image.data;
@ -1291,9 +1296,9 @@ sixel_add_many(struct terminal *term, uint8_t c, unsigned count)
int width = term->sixel.image.width;
if (unlikely(col + count - 1 >= width)) {
width = col + count;
if (unlikely(!resize_horizontally(term, width)))
return;
resize_horizontally(term, col + count);
width = term->sixel.image.width;
count = min(count, width - col);
}
uint32_t color = term->sixel.color;
@ -1412,7 +1417,8 @@ decgra(struct terminal *term, uint8_t c)
/* This ensures the sixels final image size is *at least*
* this large */
term->sixel.max_non_empty_row_no = pv - 1;
term->sixel.max_non_empty_row_no =
min(pv, term->sixel.image.height) - 1;
}
term->sixel.state = SIXEL_DECSIXEL;