[x11drv] Fix two clipboard bugs. Fixes BadAtom crash (bug 4601)

Dan Kegel dank at kegel.com
Sun Apr 9 16:47:21 CDT 2006


[crap.  sent to wine-devel by mistake first time.  Sometimes I feel
like the Klondike Koder.]

[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


--
Wine for Windows ISVs: http://kegel.com/wine/isv



More information about the wine-patches mailing list