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