Merge branch 'sixel-repeat-edge-cases'

This commit is contained in:
Daniel Eklöf 2022-02-04 18:14:32 +01:00
commit a5f8ed1b78
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 30 additions and 14 deletions

View file

@ -112,7 +112,7 @@
characters (e.g. emojis).
* Rendering of CSD borders when `csd.border-width > 0` and desktop
scaling has been enabled.
* Failure to launch when `exec(3):ed with an empty argv.
* Failure to launch when `exec(3)`:ed with an empty argv.
* Pasting from the primary clipboard (mouse middle clicking) did not
reset the scrollback view to the bottom.
* Wrong mouse binding triggered when doing two mouse selections in
@ -120,6 +120,9 @@
(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.
* Sixel: a repeat count of 0 in `DECGRI` now emits a single sixel.
### Security

39
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;
@ -1445,9 +1451,16 @@ decgri(struct terminal *term, uint8_t c)
unsigned count = term->sixel.param;
if (likely(count > 0))
sixel_add_many(term, c - 63, count);
else if (unlikely(count == 0))
sixel_add_many(term, c - 63, 1);
term->sixel.state = SIXEL_DECSIXEL;
break;
}
default:
term->sixel.state = SIXEL_DECSIXEL;
sixel_put(term, c);
break;
}
}