On 2022-10-24 10:30 AM, NRK wrote:
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
I have fixed the missing ksym initialization as NoSymbol, as well as
added an extra check for BufferOverflow after the second
XmbLookupString. Even though I think there's most likely no way, that
this would ever be triggered, I still think we should check, just to be
safe, since it's not such a big deal for us to check and the alternative
would be a UB if something that would cause that happened.
Patch inlined below.
---
Andy Gozas.
diff --git a/x.c b/x.c
index 2a3bd38..c8de29b 100644
--- a/x.c
+++ b/x.c
@@ -1833,9 +1833,9 @@ void
kpress(XEvent *ev)
{
XKeyEvent *e = &ev->xkey;
- KeySym ksym;
- char buf[64], *customkey;
- int len;
+ KeySym ksym = NoSymbol;
+ char buf[64], *p = NULL, *customkey;
+ int len, overflow = 0;
Rune c;
Status status;
Shortcut *bp;
@@ -1843,10 +1843,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)) {
@@ -1862,21 +1864,33 @@ kpress(XEvent *ev)
}
/* 3. composed string from input method */
+ if (overflow) {
+ p = xmalloc(overflow);
+ len = XmbLookupString(xw.ime.xic, e, p, overflow, &ksym,
&status);
+ if (status == XBufferOverflow) {
+ free(p);
+ return;
+ }
+ } 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