From f97de7500c086aa283e4b299f3f103a83438fd01 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 18 Nov 2016 22:31:29 +0800
Subject: [PATCH] uxtheme: Protect CloseThemeData() from invalid input.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Testcase by Michael Müller <michael@fds-team.de>.
---
 dlls/uxtheme/msstyles.c     | 22 ++++++++++++++++++++++
 dlls/uxtheme/msstyles.h     |  3 ++-
 dlls/uxtheme/tests/system.c |  4 ++++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c
index cee5aaf054e..5030e52a597 100644
--- a/dlls/uxtheme/msstyles.c
+++ b/dlls/uxtheme/msstyles.c
@@ -32,6 +32,7 @@
 
 #include "msstyles.h"
 
+#include "wine/exception.h"
 #include "wine/debug.h"
 #include "wine/heap.h"
 
@@ -54,6 +55,8 @@ static const WCHAR szThemesIniResource[] = {
     't','h','e','m','e','s','_','i','n','i','\0'
 };
 
+#define THEME_CLASS_SIGNATURE (('T' << 24) | ('H' << 16) | ('E' << 8) | 'M')
+
 static PTHEME_FILE tfActiveTheme;
 
 /***********************************************************************/
@@ -218,6 +221,7 @@ void MSSTYLES_CloseThemeFile(PTHEME_FILE tf)
                         pcls->partstate = ps->next;
                         heap_free(ps);
                     }
+                    pcls->signature = 0;
                     heap_free(pcls);
                 }
             }
@@ -449,6 +453,7 @@ static PTHEME_CLASS MSSTYLES_AddClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWST
     if(cur) return cur;
 
     cur = heap_alloc(sizeof(*cur));
+    cur->signature = THEME_CLASS_SIGNATURE;
     cur->hTheme = tf->hTheme;
     lstrcpyW(cur->szAppName, pszAppName);
     lstrcpyW(cur->szClassName, pszClassName);
@@ -1042,6 +1047,23 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList)
  */
 HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc)
 {
+    __TRY
+    {
+        if (tc->signature != THEME_CLASS_SIGNATURE)
+            tc = NULL;
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        tc = NULL;
+    }
+    __ENDTRY
+
+    if (!tc)
+    {
+        WARN("Invalid theme class handle\n");
+        return E_HANDLE;
+    }
+
     MSSTYLES_CloseThemeFile (tc->tf);
     return S_OK;
 }
diff --git a/dlls/uxtheme/msstyles.h b/dlls/uxtheme/msstyles.h
index 0b7e1ab35cc..ba10ac82b82 100644
--- a/dlls/uxtheme/msstyles.h
+++ b/dlls/uxtheme/msstyles.h
@@ -49,6 +49,7 @@ typedef struct _THEME_PARTSTATE {
 struct _THEME_FILE;
 
 typedef struct _THEME_CLASS {
+    DWORD signature;
     HMODULE hTheme;
     struct _THEME_FILE* tf;
     WCHAR szAppName[MAX_THEME_APP_NAME];
@@ -63,7 +64,7 @@ typedef struct _THEME_IMAGE {
     WCHAR name[MAX_PATH];
     HBITMAP image;
     BOOL hasAlpha;
-    
+
     struct _THEME_IMAGE *next;
 } THEME_IMAGE, *PTHEME_IMAGE;
 
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c
index b3a861eaa6b..1cfafb30e2a 100644
--- a/dlls/uxtheme/tests/system.c
+++ b/dlls/uxtheme/tests/system.c
@@ -189,6 +189,10 @@ static void test_OpenThemeData(void)
             "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
             GetLastError());
 
+    /* Close invalid handle */
+    hRes = CloseThemeData((HTHEME)0xdeadbeef);
+    ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
+
     if (!bThemeActive)
     {
         SetLastError(0xdeadbeef);
-- 
2.20.1