---
 x.c | 41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/x.c b/x.c
index 2a3bd38..8d14fc1 100644
--- a/x.c
+++ b/x.c
@@ -1834,8 +1834,10 @@ kpress(XEvent *ev)
 {
        XKeyEvent *e = &ev->xkey;
        KeySym ksym;
-       char buf[64], *customkey;
-       int len;
+       char *buf = NULL, *customkey;
+       int len = 0;
+       int buf_size = 64;
+       int critical = - 1;
        Rune c;
        Status status;
        Shortcut *bp;
@@ -1843,27 +1845,42 @@ kpress(XEvent *ev)
        if (IS_SET(MODE_KBDLOCK))
                return;
 
-       if (xw.ime.xic)
-               len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, 
&status);
-       else
-               len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
+reallocbuf:
+       if (critical > 0)
+               goto cleanup;
+       if (buf)
+               free(buf);
+
+       buf = xmalloc((buf_size) * sizeof(char));
+       critical += 1;
+
+       if (xw.ime.xic) {
+               len = XmbLookupString(xw.ime.xic, e, buf, buf_size, &ksym, 
&status);
+               if (status == XBufferOverflow) {
+                       buf_size = len;
+                       goto reallocbuf;
+               }
+       } else {
+               // XXX: May cut large inputs
+               len = XLookupString(e, buf, buf_size, &ksym, NULL);
+       }
        /* 1. shortcuts */
        for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
                if (ksym == bp->keysym && match(bp->mod, e->state)) {
                        bp->func(&(bp->arg));
-                       return;
+                       goto cleanup;
                }
        }
 
        /* 2. custom keys from config.h */
        if ((customkey = kmap(ksym, e->state))) {
                ttywrite(customkey, strlen(customkey), 1);
-               return;
+               goto cleanup;
        }
 
        /* 3. composed string from input method */
        if (len == 0)
-               return;
+               goto cleanup;
        if (len == 1 && e->state & Mod1Mask) {
                if (IS_SET(MODE_8BIT)) {
                        if (*buf < 0177) {
@@ -1876,7 +1893,11 @@ kpress(XEvent *ev)
                        len = 2;
                }
        }
-       ttywrite(buf, len, 1);
+       if (len <= buf_size)
+               ttywrite(buf, len, 1);
+cleanup:
+       if (buf)
+               free(buf);
 }
 
 void
-- 
2.38.1


Reply via email to