On Mon, Oct 24, 2022 at 01:10:29PM +0300, Santtu Lakkala wrote: > The dynmaic[sic] version incorrectly passes sizeof(buf), where buf is char > *, as the size of buffer in the "happy case" leading to unnecessary hits to > the dynamic path.
Ah yes, the classic. Attached ammended version of the dynmaic patch. A bit more invasive (but hopefully correct) than the previous patch. - NRK
>From 920799cb2a3526f2398caf98ebf0815fb323ff3f Mon Sep 17 00:00:00 2001 From: NRK <[email protected]> Date: Mon, 24 Oct 2022 15:49:18 +0600 Subject: [PATCH] fix: buffer overflow when handling composed input XmbLookupString may leave buf as well as ksym uninitialized. initialize ksym to NoSymbol. track weather we need a larger buffer or not, and dynamically allocate if needed. Reported-by: Andy Gozas <[email protected]> --- x.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/x.c b/x.c index f70e3fb..6a4ed46 100644 --- a/x.c +++ b/x.c @@ -1847,8 +1847,8 @@ kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym ksym; - char buf[64], *customkey; - int len; + char buf[64], *p = NULL, *customkey; + int len, overflow = 0; Rune c; Status status; const Shortcut *bp; @@ -1856,10 +1856,12 @@ kpress(XEvent *ev) if (IS_SET(MODE_KBDLOCK)) return; - if (xw.ime.xic) + if (xw.ime.xic) { len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); - else + overflow = status == XBufferOverflow ? len : 0; + } else { len = XLookupString(e, buf, sizeof buf, &ksym, NULL); + } /* 1. shortcuts */ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { if (ksym == bp->keysym && match(bp->mod, e->state)) { @@ -1875,21 +1877,29 @@ kpress(XEvent *ev) } /* 3. composed string from input method */ + if (overflow) { + p = xmalloc(overflow); + len = XmbLookupString(xw.ime.xic, e, p, overflow, &ksym, &status); + } else { + p = buf; + } if (len == 0) return; if (len == 1 && e->state & Mod1Mask) { if (IS_SET(MODE_8BIT)) { - if (*buf < 0177) { - c = *buf | 0x80; - len = utf8encode(c, buf); + if (*p < 0177) { + c = *p | 0x80; + len = utf8encode(c, p); } } else { - buf[1] = buf[0]; - buf[0] = '\033'; + p[1] = p[0]; + p[0] = '\033'; len = 2; } } - ttywrite(buf, len, 1); + ttywrite(p, len, 1); + if (overflow) + free(p); } void -- 2.35.1
