kitty: fix Unicode placeholder rendering

csiparse() mishandled colon-form SGR (ESC[38:2:r:g:bm): the undercurl
patch's readcolonargs() swallowed the colour sub-parameters, so the
foreground never became a truecolor value and the image id encoded in
it could not be recovered. Only consume colon args for non-colour
attributes, and only while ';' is still the separator.

Also suppress the U+10EEEE placeholder glyph itself when drawing, so
only the image shows.

Fixes the base64 decoder's signed shift overflow found by UBSan.
This commit is contained in:
a 2026-09-06 22:30:56 -05:00
parent a4f4f96c62
commit 56c4253a87
No known key found for this signature in database
GPG Key ID: 2F22877AA4DFDADB
3 changed files with 22 additions and 3 deletions

View File

@ -177,7 +177,8 @@ static size_t
kitty_b64decode(const char *src, size_t srclen, char *dst) kitty_b64decode(const char *src, size_t srclen, char *dst)
{ {
size_t i, o = 0; size_t i, o = 0;
int acc = 0, bits = 0; uint32_t acc = 0;
int bits = 0;
unsigned char c; unsigned char c;
for (i = 0; i < srclen; i++) { for (i = 0; i < srclen; i++) {
@ -188,7 +189,7 @@ kitty_b64decode(const char *src, size_t srclen, char *dst)
continue; continue;
if (!b64tab[c] && c != 'A') if (!b64tab[c] && c != 'A')
continue; continue;
acc = (acc << 6) | b64tab[c]; acc = ((acc << 6) | (uint32_t)b64tab[c]) & 0xffffff;
bits += 6; bits += 6;
if (bits >= 8) { if (bits >= 8) {
bits -= 8; bits -= 8;

7
st.c
View File

@ -1524,6 +1524,13 @@ csiparse(void)
csiescseq.arg[csiescseq.narg++] = v; csiescseq.arg[csiescseq.narg++] = v;
p = np; p = np;
#if UNDERCURL_PATCH #if UNDERCURL_PATCH
/*
* Colon sub-parameters are only consumed as "colon args" for the
* underline style (SGR 4:x). For the colour attributes 38/48/58 the
* sub-parameters are the colour spec itself and must be parsed as
* ordinary arguments, e.g. ESC[38:2:r:g:bm.
*/
if (sep == ';' && v != 38 && v != 48 && v != 58)
readcolonargs(&p, csiescseq.narg-1, csiescseq.carg); readcolonargs(&p, csiescseq.narg-1, csiescseq.carg);
#endif // UNDERCURL_PATCH #endif // UNDERCURL_PATCH
if (sep == ';' && *p == ':') if (sep == ';' && *p == ':')

11
x.c
View File

@ -3060,6 +3060,17 @@ xdrawline(Line line, int x1, int y1, int x2)
Glyph base, new; Glyph base, new;
XftGlyphFontSpec *specs; XftGlyphFontSpec *specs;
#if KITTY_GRAPHICS_PATCH
/* the U+10EEEE placeholder is never drawn as text, only its image is */
for (x = x1; x < x2; x++) {
if (line[x].mode & ATTR_KITTYPH) {
line[x].u = ' ';
line[x].mode &= ~(ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE |
ATTR_STRUCK | ATTR_WIDE | ATTR_WDUMMY);
}
}
#endif // KITTY_GRAPHICS_PATCH
numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1); numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1);
/* Draw line in 2 passes: background and foreground. This way wide glyphs /* Draw line in 2 passes: background and foreground. This way wide glyphs