[x11drv] Fix two clipboard bugs. Fixes BadAtom crash (bug 4601)
Dan Kegel
dank at kegel.com
Sun Apr 9 16:33:06 CDT 2006
[Is it safe to call intern_atoms() inside the event handler like this?]
Changelog:
Fix two clipboard problems that caused BadAtom crashes (bug 4601)
and caused some clipboard formats to not be exported properly
Patch also at http://kegel.com/wine/badatom3.patch if this gets mangled by
gmail.
dlls/x11drv/clipboard.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
Index: dlls/x11drv/clipboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/clipboard.c,v
retrieving revision 1.51
diff -d -u -r1.51 clipboard.c
--- dlls/x11drv/clipboard.c 22 Feb 2006 21:31:52 -0000 1.51
+++ dlls/x11drv/clipboard.c 9 Apr 2006 21:25:15 -0000
@@ -1784,6 +1784,10 @@
if (names)
{
wine_tsx11_lock();
+ /* FIXME: we're at the mercy of the app sending the event here.
+ * Currently if they send a bogus atom, we will crash.
+ * We should handle BadAtom errors gracefully in this call.
+ */
XGetAtomNames( display, atoms, nb_atoms, names );
wine_tsx11_unlock();
for (i = 0; i < nb_atoms; i++)
@@ -2790,6 +2794,13 @@
LPWINE_CLIPFORMAT lpFormats;
LPWINE_CLIPDATA lpData;
+ /* Create X atoms for any clipboard types which don't have atoms yet.
+ * This avoids sending bogus zero atoms.
+ * Without this, copying might not have access to all clipboard types.
+ * FIXME: is it safe to call this here?
+ */
+ intern_atoms();
+
/*
* Count the number of items we wish to expose as selection targets.
*/
@@ -2804,7 +2815,7 @@
while (lpFormats)
{
if ((lpFormats->wFormatID == lpData->wFormatID) &&
- lpFormats->lpDrvExportFunc)
+ lpFormats->lpDrvExportFunc && lpFormats->drvData)
cTargets++;
lpFormats = lpFormats->NextFormat;
@@ -2832,8 +2843,15 @@
while (lpFormats)
{
if ((lpFormats->wFormatID == lpData->wFormatID) &&
- lpFormats->lpDrvExportFunc)
- targets[i++] = lpFormats->drvData;
+ lpFormats->lpDrvExportFunc) {
+ /* Don't send zeroes, lest receiver choke on XGetAtomName() */
+ if (lpFormats->drvData) {
+ assert(i < cTargets);
+ targets[i++] = lpFormats->drvData;
+ } else {
+ WARN("bug: ignoring zero atom...\n");
+ }
+ }
lpFormats = lpFormats->NextFormat;
}
@@ -2841,6 +2859,7 @@
lpData = lpData->NextData;
}
while (lpData != ClipData);
+ assert(i == cTargets);
wine_tsx11_lock();
@@ -2849,7 +2868,10 @@
unsigned int i;
for ( i = 0; i < cTargets; i++)
{
- if (targets[i])
+ /* intern_atoms() should make these nonzero.
+ * We checked before adding them to the array, just to be safe.
+ */
+ assert(targets[i]);
{
char *itemFmtName = XGetAtomName(display, targets[i]);
TRACE("\tAtom# %d: Property %ld Type %s\n", i,
targets[i], itemFmtName);
--
Wine for Windows ISVs: http://kegel.com/wine/isv
More information about the wine-devel
mailing list