From: Zhiyi Zhang Subject: [PATCH 1/3] atl: Avoid NULL pointer reference in AtlComModuleGetClassObject(). Message-Id: Date: Fri, 01 Jul 2022 08:00:33 +0000 In-Reply-To: References: From: Zhiyi Zhang Fix crash in CAXA CAD when clicking component library. Signed-off-by: Zhiyi Zhang --- configure.ac | 1 + dlls/atl/atl.c | 4 +- dlls/atl100/tests/atl.c | 27 +++++++++++ dlls/atl110/tests/Makefile.in | 6 +++ dlls/atl110/tests/atl.c | 86 +++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 dlls/atl110/tests/Makefile.in create mode 100644 dlls/atl110/tests/atl.c diff --git a/configure.ac b/configure.ac index 9ad1b19164c..f26e9cde350 100644 --- a/configure.ac +++ b/configure.ac @@ -2394,6 +2394,7 @@ WINE_CONFIG_MAKEFILE(dlls/atl/tests) WINE_CONFIG_MAKEFILE(dlls/atl100) WINE_CONFIG_MAKEFILE(dlls/atl100/tests) WINE_CONFIG_MAKEFILE(dlls/atl110) +WINE_CONFIG_MAKEFILE(dlls/atl110/tests) WINE_CONFIG_MAKEFILE(dlls/atl80) WINE_CONFIG_MAKEFILE(dlls/atl80/tests) WINE_CONFIG_MAKEFILE(dlls/atl90) diff --git a/dlls/atl/atl.c b/dlls/atl/atl.c index 87a24e33ed7..d501e7a6d76 100644 --- a/dlls/atl/atl.c +++ b/dlls/atl/atl.c @@ -482,7 +482,7 @@ HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, return E_INVALIDARG; for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) { - if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) { + if(*iter && IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) { if(!(*iter)->pCF) hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCF); if((*iter)->pCF) @@ -507,7 +507,7 @@ HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, return E_INVALIDARG; for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) { - if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) { + if(*iter && IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) { if(!(*iter)->pCache->pCF) hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCache->pCF); if((*iter)->pCache->pCF) diff --git a/dlls/atl100/tests/atl.c b/dlls/atl100/tests/atl.c index e161878f8ea..e002af0d24c 100644 --- a/dlls/atl100/tests/atl.c +++ b/dlls/atl100/tests/atl.c @@ -1062,6 +1062,32 @@ static void test_AtlAxCreateControl(void) DestroyWindow(hwnd); } +static void test_AtlComModuleGetClassObject(void) +{ + _ATL_OBJMAP_ENTRY *null_entry = NULL; + _ATL_COM_MODULE module; + HRESULT hr; + void *ret; + + /* Test NULL module */ + hr = AtlComModuleGetClassObject(NULL, &GUID_NULL, &IID_NULL, &ret); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + /* Test NULL m_ppAutoObjMapFirst and m_ppAutoObjMapLast */ + module.cbSize = sizeof(module); + module.m_ppAutoObjMapFirst = NULL; + module.m_ppAutoObjMapLast = NULL; + hr = AtlComModuleGetClassObject(&module, &GUID_NULL, &IID_NULL, &ret); + ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + + /* Test m_ppAutoObjMapFirst and m_ppAutoObjMapLast both pointing to a NULL entry */ + module.cbSize = sizeof(module); + module.m_ppAutoObjMapFirst = &null_entry; + module.m_ppAutoObjMapLast = &null_entry; + hr = AtlComModuleGetClassObject(&module, &GUID_NULL, &IID_NULL, &ret); + ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); +} + START_TEST(atl) { if (!register_class()) @@ -1077,6 +1103,7 @@ START_TEST(atl) test_ax_win(); test_AtlAxAttachControl(); test_AtlAxCreateControl(); + test_AtlComModuleGetClassObject(); CoUninitialize(); } diff --git a/dlls/atl110/tests/Makefile.in b/dlls/atl110/tests/Makefile.in new file mode 100644 index 00000000000..528c9180dc8 --- /dev/null +++ b/dlls/atl110/tests/Makefile.in @@ -0,0 +1,6 @@ +TESTDLL = atl110.dll +IMPORTS = uuid ole32 +EXTRADEFS = -D_ATL_VER=_ATL_VER_110 + +C_SRCS = \ + atl.c diff --git a/dlls/atl110/tests/atl.c b/dlls/atl110/tests/atl.c new file mode 100644 index 00000000000..12f3518b429 --- /dev/null +++ b/dlls/atl110/tests/atl.c @@ -0,0 +1,86 @@ +/* + * Copyright 2022 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#define COBJMACROS +#define CONST_VTABLE + +#include +#include +#include +#include + +#include + +static HRESULT (WINAPI *pAtlComModuleGetClassObject)(_ATL_COM_MODULE *, REFCLSID, REFIID, void **); + +static HMODULE atl110; + +static void init_functions(void) +{ + atl110 = LoadLibraryA("atl110.dll"); + +#define X(f) p##f = (void *)GetProcAddress(atl110, #f); + X(AtlComModuleGetClassObject) +#undef X +} + +static void test_AtlComModuleGetClassObject(void) +{ + _ATL_OBJMAP_ENTRY_EX *null_entry = NULL; + _ATL_COM_MODULE module; + HRESULT hr; + void *ret; + + if (!pAtlComModuleGetClassObject) + { + win_skip("AtlComModuleGetClassObject() is unavailable.\n"); + return; + } + + /* Test NULL module */ + hr = pAtlComModuleGetClassObject(NULL, &GUID_NULL, &IID_NULL, &ret); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + /* Test NULL m_ppAutoObjMapFirst and m_ppAutoObjMapLast */ + module.cbSize = sizeof(module); + module.m_ppAutoObjMapFirst = NULL; + module.m_ppAutoObjMapLast = NULL; + hr = pAtlComModuleGetClassObject(&module, &GUID_NULL, &IID_NULL, &ret); + ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + + /* Test m_ppAutoObjMapFirst and m_ppAutoObjMapLast both pointing to a NULL entry */ + module.cbSize = sizeof(module); + module.m_ppAutoObjMapFirst = &null_entry; + module.m_ppAutoObjMapLast = &null_entry; + hr = pAtlComModuleGetClassObject(&module, &GUID_NULL, &IID_NULL, &ret); + ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); +} + +START_TEST(atl) +{ + CoInitialize(NULL); + init_functions(); + + test_AtlComModuleGetClassObject(); + + FreeLibrary(atl110); + CoUninitialize(); +} -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/358