[PATCH] user32/caret.c: Avoid SetSystemTimer / KillSystemTimer with null hwnd.

Robert Schlicht patch at rschlicht.eu
Fri Feb 14 03:16:39 CST 2020


Check that hwnd is not null before calling SetSystemTimer or
KillSystemTimer in functions ShowCaret, HideCaret and SetCaretPos.

Reason:
If there is no caret window, the call in ShowCaret,
  SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
will create (and leak) a timer since TIMERID is not used if hwnd is
null. Similar issues affect the other functions.

Illustration:
Depending on your system (Alt+Tab or Alt+Esc switching between
applications), this is seen even in standard applications:
(1) Start Notepad.exe.
(2) Hold down Alt (do not release).
(3) Rick-click to open the context menu.
(4) Switch to another application without first returning the focus to
    the edit field by pressing Tab or Esc. (The context menu should 
    remain open.)
(5) Close the context menu while Notepad is not active.
Now SetSystemTimer has been called with a null hwnd (via ShowCaret(0)
in MENU_ExitTracking() in menu.c) and a timer has been leaked. When
you switch back to Notepad, the caret flashes more frequently /
irregularly. The patch fixes this.

Signed-off-by: Robert Schlicht <patch at rschlicht.eu>
---
 dlls/user32/caret.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/dlls/user32/caret.c b/dlls/user32/caret.c
index 686dade410..edcbc3cd6b 100644
--- a/dlls/user32/caret.c
+++ b/dlls/user32/caret.c
@@ -269,7 +269,7 @@ BOOL WINAPI SetCaretPos( INT x, INT y )
         }
     }
     SERVER_END_REQ;
-    if (ret && !hidden && (x != r.left || y != r.top))
+    if (ret && hwnd && !hidden && (x != r.left || y != r.top))
     {
         if (old_state) CARET_DisplayCaret( hwnd, &r );
         r.right += x - r.left;
@@ -314,7 +314,7 @@ BOOL WINAPI HideCaret( HWND hwnd )
     }
     SERVER_END_REQ;
 
-    if (ret && !hidden)
+    if (ret && hwnd && !hidden)
     {
         if (old_state) CARET_DisplayCaret( hwnd, &r );
         KillSystemTimer( hwnd, TIMERID );
@@ -352,7 +352,7 @@ BOOL WINAPI ShowCaret( HWND hwnd )
     }
     SERVER_END_REQ;
 
-    if (ret && (hidden == 1))  /* hidden was 1 so it's now 0 */
+    if (ret && hwnd && (hidden == 1))  /* hidden was 1 so it's now 0 */
     {
         CARET_DisplayCaret( hwnd, &r );
         SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
-- 
2.17.1




More information about the wine-devel mailing list