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