[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