Alexandre Julliard : winex11: Fix X11DRV_CLIPBOARD_ReadProperty to read data in larger chunks and to properly null-terminate the buffer .
Alexandre Julliard
julliard at winehq.org
Wed Mar 26 09:16:12 CDT 2008
Module: wine
Branch: master
Commit: a71998d0a60fb3c67aefe1938cc794f8263a7591
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a71998d0a60fb3c67aefe1938cc794f8263a7591
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Mar 26 12:14:41 2008 +0100
winex11: Fix X11DRV_CLIPBOARD_ReadProperty to read data in larger chunks and to properly null-terminate the buffer.
---
dlls/winex11.drv/clipboard.c | 87 +++++++++++++++++------------------------
1 files changed, 36 insertions(+), 51 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 0dba308..2996857 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -72,6 +72,7 @@
# include <unistd.h>
#endif
#include <fcntl.h>
+#include <limits.h>
#include <time.h>
#include <assert.h>
@@ -2006,71 +2007,55 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Window w, Atom prop,
Display *display = thread_display();
Atom atype = AnyPropertyType;
int aformat;
- unsigned long total, nitems, remain, val_cnt;
- long reqlen, bwc;
- unsigned char* val;
- unsigned char* buffer;
+ unsigned long pos = 0, nitems, remain, count;
+ unsigned char *val = NULL, *buffer;
if (prop == None)
return FALSE;
- TRACE("Reading property %d from X window %d\n",
- (unsigned int)prop, (unsigned int)w);
+ TRACE("Reading property %lu from X window %lx\n", prop, w);
- /*
- * First request a zero length in order to figure out the request size.
- */
- wine_tsx11_lock();
- if(XGetWindowProperty(display,w,prop,0,0,False, AnyPropertyType,
- &atype, &aformat, &nitems, &remain, &buffer) != Success)
- {
- wine_tsx11_unlock();
- WARN("Failed to get property size\n");
- return FALSE;
- }
-
- /* Free zero length return data if any */
- if (buffer)
+ for (;;)
{
- XFree(buffer);
- buffer = NULL;
- }
-
- bwc = aformat/8;
- reqlen = remain * bwc;
-
- TRACE("Retrieving %ld bytes\n", reqlen);
-
- val = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, reqlen);
+ wine_tsx11_lock();
+ if (XGetWindowProperty(display, w, prop, pos, INT_MAX / 4, False,
+ AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success)
+ {
+ wine_tsx11_unlock();
+ WARN("Failed to read property\n");
+ HeapFree( GetProcessHeap(), 0, val );
+ return FALSE;
+ }
- /* Read property in 4K blocks */
- for (total = 0, val_cnt = 0; remain;)
- {
- if (XGetWindowProperty(display, w, prop, (total / 4), 4096, False,
- AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success)
- {
- wine_tsx11_unlock();
- WARN("Failed to read property\n");
- HeapFree(GetProcessHeap(), 0, val);
- return FALSE;
- }
+ count = nitems * (aformat / 8);
+ if (!val) *data = HeapAlloc( GetProcessHeap(), 0, pos * sizeof(int) + count + 1 );
+ else *data = HeapReAlloc( GetProcessHeap(), 0, val, pos * sizeof(int) + count + 1 );
- bwc = aformat/8;
- memcpy(&val[val_cnt], buffer, nitems * bwc);
- val_cnt += nitems * bwc;
- total += nitems*bwc;
- XFree(buffer);
+ if (!*data)
+ {
+ XFree( buffer );
+ wine_tsx11_unlock();
+ HeapFree( GetProcessHeap(), 0, val );
+ return FALSE;
+ }
+ val = *data;
+ memcpy( (int *)val + pos, buffer, count );
+ XFree( buffer );
+ wine_tsx11_unlock();
+ if (!remain)
+ {
+ *datasize = pos * sizeof(int) + count;
+ val[*datasize] = 0;
+ break;
+ }
+ pos += count / sizeof(int);
}
/* Delete the property on the window now that we are done
* This will send a PropertyNotify event to the selection owner. */
+ wine_tsx11_lock();
XDeleteProperty(display, w, prop);
-
wine_tsx11_unlock();
-
- *data = val;
- *datasize = total;
-
return TRUE;
}
More information about the wine-cvs
mailing list