From 56c4253a87f15968a41d0ef9149cf72af04ad39d Mon Sep 17 00:00:00 2001 From: a Date: Sun, 6 Sep 2026 22:30:56 -0500 Subject: [PATCH] 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. --- kitty.c | 5 +++-- st.c | 9 ++++++++- x.c | 11 +++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/kitty.c b/kitty.c index 135711d..11de61b 100644 --- a/kitty.c +++ b/kitty.c @@ -177,7 +177,8 @@ static size_t kitty_b64decode(const char *src, size_t srclen, char *dst) { size_t i, o = 0; - int acc = 0, bits = 0; + uint32_t acc = 0; + int bits = 0; unsigned char c; for (i = 0; i < srclen; i++) { @@ -188,7 +189,7 @@ kitty_b64decode(const char *src, size_t srclen, char *dst) continue; if (!b64tab[c] && c != 'A') continue; - acc = (acc << 6) | b64tab[c]; + acc = ((acc << 6) | (uint32_t)b64tab[c]) & 0xffffff; bits += 6; if (bits >= 8) { bits -= 8; diff --git a/st.c b/st.c index b3fbf25..8694e60 100644 --- a/st.c +++ b/st.c @@ -1524,7 +1524,14 @@ csiparse(void) csiescseq.arg[csiescseq.narg++] = v; p = np; #if UNDERCURL_PATCH - readcolonargs(&p, csiescseq.narg-1, csiescseq.carg); + /* + * 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); #endif // UNDERCURL_PATCH if (sep == ';' && *p == ':') sep = ':'; /* allow override to colon once */ diff --git a/x.c b/x.c index becc042..2425e7e 100644 --- a/x.c +++ b/x.c @@ -3060,6 +3060,17 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; 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); /* Draw line in 2 passes: background and foreground. This way wide glyphs