[PATCH] user32: Disallow setting some of window values with mismatching size.

Nikolay Sivov nsivov at codeweavers.com
Mon Feb 25 04:42:24 CST 2019


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46712
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/user32/tests/win.c | 71 +++++++++++++++++++++++++++++++++++++++++
 dlls/user32/win.c       | 38 +++++++++++++++++++++-
 2 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 3444abaf96..4fb9cc1a0c 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -6330,6 +6330,75 @@ static int check_error(DWORD actual, DWORD expected)
     return (!sets_last_error && (actual == 0xdeadbeef)) || (actual == expected);
 }
 
+static void test_set_window_long_size(void)
+{
+#ifdef _WIN64
+    WNDPROC old_window_procW, old_window_proc2W;
+    LONG_PTR retval;
+    HWND hwnd;
+    LONG ret;
+
+    /* It's not allowed to set or get 64-bit pointer values using 32-bit functions. */
+    hwnd = CreateWindowExA(0, "MainWindowClass", "Child window", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CHILD |
+            WS_MAXIMIZEBOX | WS_VISIBLE, 100, 100, 200, 200, hwndMain, 0, GetModuleHandleA(NULL), NULL);
+    ok(hwnd != NULL, "Failed to create test window.\n");
+
+    /* GWLP_WNDPROC */
+    SetLastError(0xdeadbeef);
+    old_window_procW = (WNDPROC)(LONG_PTR)GetWindowLongA(hwnd, GWLP_WNDPROC);
+    ok(!old_window_procW && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n");
+
+    old_window_procW = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC);
+    ok(!!old_window_procW, "Unexpected window proc.\n");
+
+    SetLastError(0xdeadbeef);
+    old_window_proc2W = (WNDPROC)(LONG_PTR)SetWindowLongA(hwnd, GWLP_WNDPROC, 0xdeadbeef);
+    ok(!old_window_proc2W && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n");
+
+    old_window_proc2W = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC);
+    ok(old_window_proc2W == old_window_procW, "Unexpected window proc.\n");
+
+    /* GWLP_USERDATA */
+    SetWindowLongPtrA(hwnd, GWLP_USERDATA, ((LONG_PTR)1 << 32) | 123);
+    ret = GetWindowLongA(hwnd, GWLP_USERDATA);
+    ok(ret == 123, "Unexpected user data %#x.\n", ret);
+    retval = GetWindowLongPtrA(hwnd, GWLP_USERDATA);
+    ok(retval > 123, "Unexpected user data.\n");
+
+    /* GWLP_ID */
+    ret = SetWindowLongA(hwnd, GWLP_ID, 1);
+    ok(!ret, "Unexpected id %#x.\n", ret);
+
+    ret = GetWindowLongA(hwnd, GWLP_ID);
+    ok(ret == 1, "Unexpected id %#x.\n", ret);
+
+    SetWindowLongPtrA(hwnd, GWLP_ID, ((LONG_PTR)1 << 32) | 123);
+    ret = GetWindowLongA(hwnd, GWLP_ID);
+    ok(ret == 123, "Unexpected user data %#x.\n", ret);
+    retval = GetWindowLongPtrA(hwnd, GWLP_ID);
+    ok(retval > 123, "Unexpected user data.\n");
+
+    /* GWLP_HINSTANCE */
+    retval = GetWindowLongPtrA(hwnd, GWLP_HINSTANCE);
+    ok(retval == (LONG_PTR)GetModuleHandleA(NULL), "Unexpected instance %#lx.\n", retval);
+
+    SetLastError(0xdeadbeef);
+    ret = GetWindowLongA(hwnd, GWLP_HINSTANCE);
+    ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret);
+
+    SetLastError(0xdeadbeef);
+    ret = SetWindowLongA(hwnd, GWLP_HINSTANCE, 1);
+    ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret);
+
+    /* GWLP_HWNDPARENT */
+    SetLastError(0xdeadbeef);
+    ret = GetWindowLongA(hwnd, GWLP_HWNDPARENT);
+    ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret);
+
+    DestroyWindow(hwnd);
+#endif
+}
+
 static void test_SetWindowLong(void)
 {
     LONG_PTR retval;
@@ -6371,6 +6440,8 @@ static void test_SetWindowLong(void)
         /* set it back to ANSI */
         SetWindowLongPtrA(hwndMain, GWLP_WNDPROC, 0);
     }
+
+    test_set_window_long_size();
 }
 
 static LRESULT WINAPI check_style_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 24b2a2ffd5..d08fa67b11 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -2299,6 +2299,20 @@ UINT WINAPI GetDpiForWindow( HWND hwnd )
     return ret;
 }
 
+static BOOL is_valid_window_value_size(INT offset, UINT size)
+{
+    switch (offset)
+    {
+#ifdef _WIN64
+        case GWLP_HWNDPARENT:
+        case GWLP_WNDPROC:
+        case GWLP_HINSTANCE:
+            return size == sizeof(LONG_PTR);
+#endif
+        default:
+            return TRUE;
+    }
+}
 
 /**********************************************************************
  *	     WIN_GetWindowLong
@@ -2312,7 +2326,15 @@ static LONG_PTR WIN_GetWindowLong( HWND hwnd, INT offset, UINT size, BOOL unicod
 
     if (offset == GWLP_HWNDPARENT)
     {
-        HWND parent = GetAncestor( hwnd, GA_PARENT );
+        HWND parent;
+
+        if (!is_valid_window_value_size( offset, size ))
+        {
+            SetLastError( ERROR_INVALID_INDEX );
+            return 0;
+        }
+
+        parent = GetAncestor( hwnd, GA_PARENT );
         if (parent == GetDesktopWindow()) parent = GetWindow( hwnd, GW_OWNER );
         return (ULONG_PTR)parent;
     }
@@ -2398,6 +2420,13 @@ static LONG_PTR WIN_GetWindowLong( HWND hwnd, INT offset, UINT size, BOOL unicod
         return retvalue;
     }
 
+    if (!is_valid_window_value_size( offset, size ))
+    {
+        SetLastError( ERROR_INVALID_INDEX );
+        WIN_ReleasePtr( wndPtr );
+        return 0;
+    }
+
     switch(offset)
     {
     case GWLP_USERDATA:  retvalue = wndPtr->userdata; break;
@@ -2474,6 +2503,13 @@ LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, B
         return SendMessageW( hwnd, WM_WINE_SETWINDOWLONG, MAKEWPARAM( offset, size ), newval );
     }
 
+    if (!is_valid_window_value_size( offset, size ))
+    {
+        SetLastError( ERROR_INVALID_INDEX );
+        WIN_ReleasePtr( wndPtr );
+        return 0;
+    }
+
     /* first some special cases */
     switch( offset )
     {
-- 
2.20.1




More information about the wine-devel mailing list