Muneyuki Noguchi : winex11: Fix a buffer overflow bug in X11DRV_KeyEvent() and X11DRV_ToUnicodeEx().
Alexandre Julliard
julliard at winehq.org
Fri Sep 12 07:01:19 CDT 2008
Module: wine
Branch: master
Commit: 18d2653c3b15a22ad0c00d5d5a701685ad5bcd85
URL: http://source.winehq.org/git/wine.git/?a=commit;h=18d2653c3b15a22ad0c00d5d5a701685ad5bcd85
Author: Muneyuki Noguchi <nogu.dev at gmail.com>
Date: Thu Sep 11 23:46:59 2008 +0900
winex11: Fix a buffer overflow bug in X11DRV_KeyEvent() and X11DRV_ToUnicodeEx().
---
dlls/winex11.drv/keyboard.c | 54 +++++++++++++++++++++++++++++++++---------
1 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index fe0e840..99b16ed 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1352,7 +1352,8 @@ static void update_lock_state(BYTE vkey, WORD scan, DWORD time)
void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
{
XKeyEvent *event = &xev->xkey;
- char Str[24];
+ char buf[24];
+ char *Str = buf;
KeySym keysym = 0;
WORD vkey = 0, bScan;
DWORD dwFlags;
@@ -1367,19 +1368,32 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
wine_tsx11_lock();
/* Clients should pass only KeyPress events to XmbLookupString */
if (xic && event->type == KeyPress)
- ascii_chars = XmbLookupString(xic, event, Str, sizeof(Str), &keysym, &status);
+ {
+ ascii_chars = XmbLookupString(xic, event, buf, sizeof(buf), &keysym, &status);
+ TRACE("XmbLookupString needs %i byte(s)\n", ascii_chars);
+ if (status == XBufferOverflow)
+ {
+ Str = HeapAlloc(GetProcessHeap(), 0, ascii_chars);
+ if (Str == NULL)
+ {
+ ERR("Failed to allocate memory!\n");
+ wine_tsx11_unlock();
+ return;
+ }
+ ascii_chars = XmbLookupString(xic, event, Str, ascii_chars, &keysym, &status);
+ }
+ }
else
- ascii_chars = XLookupString(event, Str, sizeof(Str), &keysym, NULL);
+ ascii_chars = XLookupString(event, buf, sizeof(buf), &keysym, NULL);
wine_tsx11_unlock();
TRACE_(key)("nbyte = %d, status 0x%x\n", ascii_chars, status);
- if (status == XBufferOverflow)
- ERR("Buffer Overflow need %i!\n",ascii_chars);
-
if (status == XLookupChars)
{
X11DRV_XIMLookupChars( Str, ascii_chars );
+ if (buf != Str)
+ HeapFree(GetProcessHeap(), 0, Str);
return;
}
@@ -1407,6 +1421,8 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
(event->type == KeyPress) ? "KeyPress" : "KeyRelease",
keysym, ksname, ascii_chars, debugstr_an(Str, ascii_chars));
}
+ if (buf != Str)
+ HeapFree(GetProcessHeap(), 0, Str);
wine_tsx11_lock();
vkey = EVENT_event_to_vkey(xic,event);
@@ -2419,7 +2435,8 @@ INT X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
KeySym keysym = 0;
INT ret;
int keyc;
- char lpChar[10];
+ char buf[10];
+ char *lpChar = buf;
HWND focus;
XIC xic;
Status status = 0;
@@ -2518,16 +2535,27 @@ INT X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
* e.type was set to KeyPress above.
*/
if (xic)
- ret = XmbLookupString(xic, &e, lpChar, sizeof(lpChar), &keysym, &status);
+ {
+ ret = XmbLookupString(xic, &e, buf, sizeof(buf), &keysym, &status);
+ TRACE("XmbLookupString needs %d byte(s)\n", ret);
+ if (status == XBufferOverflow)
+ {
+ lpChar = HeapAlloc(GetProcessHeap(), 0, ret);
+ if (lpChar == NULL)
+ {
+ ERR("Failed to allocate memory!\n");
+ wine_tsx11_unlock();
+ return 0;
+ }
+ ret = XmbLookupString(xic, &e, lpChar, ret, &keysym, &status);
+ }
+ }
else
- ret = XLookupString(&e, lpChar, sizeof(lpChar), &keysym, NULL);
+ ret = XLookupString(&e, buf, sizeof(buf), &keysym, NULL);
wine_tsx11_unlock();
TRACE_(key)("nbyte = %d, status 0x%x\n", ret, status);
- if (status == XBufferOverflow)
- ERR("Buffer Overflow need %d!\n", ret);
-
if (TRACE_ON(key))
{
const char *ksname;
@@ -2661,6 +2689,8 @@ INT X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
}
found:
+ if (buf != lpChar)
+ HeapFree(GetProcessHeap(), 0, lpChar);
TRACE_(key)("ToUnicode about to return %d with char %x %s\n",
ret, (ret && bufW) ? bufW[0] : 0, bufW ? "" : "(no buffer)");
return ret;
More information about the wine-cvs
mailing list