Merge pull request #342 from AndyGozas/master

Fix buffer overflow in input handling
This commit is contained in:
Luke Smith 2022-09-20 12:11:20 +00:00 committed by GitHub
commit 159f1666a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

41
x.c
View file

@ -2018,8 +2018,10 @@ kpress(XEvent *ev)
{ {
XKeyEvent *e = &ev->xkey; XKeyEvent *e = &ev->xkey;
KeySym ksym; KeySym ksym;
char buf[64], *customkey; char *buf = NULL, *customkey;
int len; int len = 0;
int buf_size = 64;
int critical = - 1;
Rune c; Rune c;
Status status; Status status;
Shortcut *bp; Shortcut *bp;
@ -2027,27 +2029,44 @@ kpress(XEvent *ev)
if (IS_SET(MODE_KBDLOCK)) if (IS_SET(MODE_KBDLOCK))
return; return;
if (xw.ime.xic) reallocbuf:
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); if (critical > 0)
else goto cleanup;
len = XLookupString(e, buf, sizeof buf, &ksym, NULL); 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 {
// Not sure how to fix this and if it is fixable
// but at least it does write something into the buffer
// so it is not as critical
len = XLookupString(e, buf, buf_size, &ksym, NULL);
}
/* 1. shortcuts */ /* 1. shortcuts */
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
if (ksym == bp->keysym && match(bp->mod, e->state)) { if (ksym == bp->keysym && match(bp->mod, e->state)) {
bp->func(&(bp->arg)); bp->func(&(bp->arg));
return; goto cleanup;
} }
} }
/* 2. custom keys from config.h */ /* 2. custom keys from config.h */
if ((customkey = kmap(ksym, e->state))) { if ((customkey = kmap(ksym, e->state))) {
ttywrite(customkey, strlen(customkey), 1); ttywrite(customkey, strlen(customkey), 1);
return; goto cleanup;
} }
/* 3. composed string from input method */ /* 3. composed string from input method */
if (len == 0) if (len == 0)
return; goto cleanup;
if (len == 1 && e->state & Mod1Mask) { if (len == 1 && e->state & Mod1Mask) {
if (IS_SET(MODE_8BIT)) { if (IS_SET(MODE_8BIT)) {
if (*buf < 0177) { if (*buf < 0177) {
@ -2060,7 +2079,11 @@ kpress(XEvent *ev)
len = 2; len = 2;
} }
} }
if (len <= buf_size)
ttywrite(buf, len, 1); ttywrite(buf, len, 1);
cleanup:
if (buf)
free(buf);
} }
void void