winex11.drv: Fix copy and paste garbage on end.

Kusanagi Kouichi slash at ma.neweb.ne.jp
Wed Mar 26 01:51:14 CDT 2008


X11DRV_CLIPBOARD_ImportXAString() and X11DRV_CLIPBOARD_ImportUTF8() check
and copy one byte after not NUL terminated string. They don't terminate
string by NUL.
X11DRV_CLIPBOARD_ImportCompoundText() only imports first part of string
if string is divided into plural part.

Fix bug #11884. http://bugs.winehq.org/show_bug.cgi?id=11884
---
 dlls/winex11.drv/clipboard.c |  100 +++++++++++++++++++++++++-----------------
 1 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 0dba308..1fdf554 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -1123,14 +1123,13 @@ HANDLE X11DRV_CLIPBOARD_ImportXAString(Window w, Atom prop)
 {
     LPBYTE lpdata;
     unsigned long cbytes;
-    LPSTR lpstr;
     unsigned long i, inlcount = 0;
-    HANDLE hText = 0;
+    HANDLE hText;
 
     if (!X11DRV_CLIPBOARD_ReadProperty(w, prop, &lpdata, &cbytes))
         return 0;
 
-    for (i = 0; i <= cbytes; i++)
+    for (i = 0; i < cbytes; i++)
     {
         if (lpdata[i] == '\n')
             inlcount++;
@@ -1138,17 +1137,21 @@ HANDLE X11DRV_CLIPBOARD_ImportXAString(Window w, Atom prop)
 
     if ((hText = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbytes + inlcount + 1)))
     {
-        lpstr = GlobalLock(hText);
+        LPSTR lpstr = GlobalLock(hText);
 
-        for (i = 0, inlcount = 0; i <= cbytes; i++)
+        if (lpstr)
         {
-            if (lpdata[i] == '\n')
-                lpstr[inlcount++] = '\r';
+            for (i = 0, inlcount = 0; i < cbytes; i++)
+            {
+                if (lpdata[i] == '\n')
+                    lpstr[inlcount++] = '\r';
 
-            lpstr[inlcount++] = lpdata[i];
-        }
+                lpstr[inlcount++] = lpdata[i];
+            }
+            lpstr[inlcount] = '\0';
 
-        GlobalUnlock(hText);
+            GlobalUnlock(hText);
+        }
     }
 
     /* Free the retrieved property data */
@@ -1174,7 +1177,7 @@ HANDLE X11DRV_CLIPBOARD_ImportUTF8(Window w, Atom prop)
     if (!X11DRV_CLIPBOARD_ReadProperty(w, prop, &lpdata, &cbytes))
         return 0;
 
-    for (i = 0; i <= cbytes; i++)
+    for (i = 0; i < cbytes; i++)
     {
         if (lpdata[i] == '\n')
             inlcount++;
@@ -1184,7 +1187,7 @@ HANDLE X11DRV_CLIPBOARD_ImportUTF8(Window w, Atom prop)
     {
         UINT count;
 
-        for (i = 0, inlcount = 0; i <= cbytes; i++)
+        for (i = 0, inlcount = 0; i < cbytes; i++)
         {
             if (lpdata[i] == '\n')
                 lpstr[inlcount++] = '\r';
@@ -1198,8 +1201,11 @@ HANDLE X11DRV_CLIPBOARD_ImportUTF8(Window w, Atom prop)
         if (hUnicodeText)
         {
             WCHAR *textW = GlobalLock(hUnicodeText);
-            MultiByteToWideChar(CP_UTF8, 0, lpstr, -1, textW, count);
-            GlobalUnlock(hUnicodeText);
+            if (textW)
+            {
+                MultiByteToWideChar(CP_UTF8, 0, lpstr, -1, textW, count);
+                GlobalUnlock(hUnicodeText);
+            }
         }
 
         HeapFree(GetProcessHeap(), 0, lpstr);
@@ -1221,8 +1227,8 @@ static HANDLE X11DRV_CLIPBOARD_ImportCompoundText(Window w, Atom prop)
 {
     Display *display = thread_display();
     int i, j;
-    char** srcstr;
-    int count, lcount;
+    char **list, *srcstr;
+    int count;
     int srclen, destlen;
     HANDLE hUnicodeText;
     XTextProperty txtprop;
@@ -1234,47 +1240,59 @@ static HANDLE X11DRV_CLIPBOARD_ImportCompoundText(Window w, Atom prop)
         return 0;
     }
 
-    XmbTextPropertyToTextList(display, &txtprop, &srcstr, &count);
+    XmbTextPropertyToTextList(display, &txtprop, &list, &count);
+    XFree(txtprop.value);
     wine_tsx11_unlock();
 
     TRACE("Importing %d line(s)\n", count);
 
-    /* Compute number of lines */
-    srclen = strlen(srcstr[0]);
-    for (i = 0, lcount = 0; i <= srclen; i++)
+    for (i = 0, srclen = 0; i < count; ++i)
     {
-        if (srcstr[0][i] == '\n')
-            lcount++;
+        for (j = 0; list[i][j]; ++j)
+        {
+            if (list[i][j] == '\n')
+                srclen++;
+        }
+        srclen += j;
     }
 
-    destlen = MultiByteToWideChar(CP_UNIXCP, 0, srcstr[0], -1, NULL, 0);
-
-    TRACE("lcount = %d, destlen=%d, srcstr %s\n", lcount, destlen, srcstr[0]);
-
-    if ((hUnicodeText = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (destlen + lcount + 1) * sizeof(WCHAR))))
+    srcstr = HeapAlloc(GetProcessHeap(), 0, srclen + 1);
+    if (!srcstr)
     {
-        WCHAR *deststr = GlobalLock(hUnicodeText);
-        MultiByteToWideChar(CP_UNIXCP, 0, srcstr[0], -1, deststr, destlen);
+        wine_tsx11_lock();
+        XFreeStringList(list);
+        wine_tsx11_unlock();
+        return 0;
+    }
 
-        if (lcount)
+    for (i = 0, destlen = 0; i < count; ++i)
+    {
+        for (j = 0; list[i][j]; ++j, ++destlen)
         {
-            for (i = destlen - 1, j = destlen + lcount - 1; i >= 0; i--, j--)
-            {
-                deststr[j] = deststr[i];
-
-                if (deststr[i] == '\n')
-                    deststr[--j] = '\r';
-            }
+            if (list[i][j] == '\n')
+                srcstr[destlen++] = '\r';
+            srcstr[destlen] = list[i][j];
         }
-
-        GlobalUnlock(hUnicodeText);
     }
+    srcstr[destlen] = '\0';
 
     wine_tsx11_lock();
-    XFreeStringList(srcstr);
-    XFree(txtprop.value);
+    XFreeStringList(list);
     wine_tsx11_unlock();
 
+    destlen = MultiByteToWideChar(CP_UNIXCP, 0, srcstr, -1, NULL, 0);
+    if ((hUnicodeText = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, destlen * sizeof(WCHAR))))
+    {
+        WCHAR *deststr = GlobalLock(hUnicodeText);
+        if (deststr)
+        {
+            MultiByteToWideChar(CP_UNIXCP, 0, srcstr, -1, deststr, destlen);
+            GlobalUnlock(hUnicodeText);
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, srcstr);
+
     return hUnicodeText;
 }
 
-- 
1.5.4.4




More information about the wine-patches mailing list