[4/4] user32: Prevent clipboard viewers that change the clipboard from going into an infinite loop.

Alexander Scott-Johns alexander.scott.johns at googlemail.com
Tue Sep 22 20:17:13 CDT 2009


-------------- next part --------------
From 8219ed3a9c154e3b848c06886f2bc83d58009e3c Mon Sep 17 00:00:00 2001
From: Alexander Scott-Johns <alexander.scott.johns at googlemail.com>
Date: Wed, 23 Sep 2009 01:43:19 +0100
Subject: user32: Prevent clipboard viewers that change the clipboard from going into an infinite loop.

---
 dlls/user32/clipboard.c |   11 ++++++++++-
 dlls/user32/tests/msg.c |    2 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c
index c69d0c3..e31804d 100644
--- a/dlls/user32/clipboard.c
+++ b/dlls/user32/clipboard.c
@@ -287,6 +287,7 @@ BOOL WINAPI OpenClipboard( HWND hWnd )
  */
 BOOL WINAPI CloseClipboard(void)
 {
+    static BOOL bRecursion = FALSE;
     BOOL bRet = FALSE;
 
     TRACE("(%d)\n", bCBHasChanged);
@@ -299,8 +300,16 @@ BOOL WINAPI CloseClipboard(void)
 
             USER_Driver->pEndClipboardUpdate();
 
-            if (hWndViewer)
+            /* If a clipboard viewer changes the clipboard, we shouldn't
+             * send another WM_DRAWCLIPBOARD message, as this could cause
+             * an infinite loop.
+             */
+            if (hWndViewer && !bRecursion)
+            {
+                bRecursion = TRUE;
                 SendMessageW(hWndViewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0);
+                bRecursion = FALSE;
+            }
 
             bCBHasChanged = FALSE;
         }
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 9208c9d..ce1367b 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -11873,7 +11873,7 @@ static void test_clipboard_viewers(void)
     clear_clipboard(hWnd2);
     /* The clipboard owner is changed in recursive_viewer_proc: */
     wm_clipboard_changed[0].wParam = (WPARAM) hWnd2;
-    ok_sequence(wm_clipboard_changed, "recursive clear clipbd (viewer=1, owner=2)", TRUE);
+    ok_sequence(wm_clipboard_changed, "recursive clear clipbd (viewer=1, owner=2)", FALSE);
 
     /* Test unregistering. */
     ChangeClipboardChain(hWnd1, NULL);
-- 
1.6.0.4


More information about the wine-patches mailing list