Module: wine Branch: master Commit: afa6cb528add488a416dbc0e7d80fd56fce52227 URL: http://source.winehq.org/git/wine.git/?a=commit;h=afa6cb528add488a416dbc0e7d...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sat Jun 6 16:09:49 2015 +0300
oledb32: Fix instance leak on error path (Valgrind).
---
dlls/oledb32/datainit.c | 21 +++++++++++++++++++-- dlls/oledb32/tests/database.c | 27 ++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/oledb32/datainit.c b/dlls/oledb32/datainit.c index 3e1f509..f9db094 100644 --- a/dlls/oledb32/datainit.c +++ b/dlls/oledb32/datainit.c @@ -424,6 +424,7 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r','=',0}; static const WCHAR msdasqlW[] = {'M','S','D','A','S','Q','L',0}; datainit *This = impl_from_IDataInitialize(iface); + BOOL datasource_created = FALSE; IDBProperties *dbprops; DBPROPSET *propset; WCHAR *prov = NULL; @@ -511,6 +512,8 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o
if (FAILED(hr) && IsEqualIID(riid, &IID_IDBInitialize)) hr = create_db_init(datasource); + + datasource_created = *datasource != NULL; }
/* now set properties */ @@ -521,7 +524,12 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o hr = IUnknown_QueryInterface(*datasource, &IID_IDBProperties, (void**)&dbprops); if (FAILED(hr)) { - WARN("provider doesn't support IDBProperties\n"); + ERR("provider doesn't support IDBProperties\n"); + if (datasource_created) + { + IUnknown_Release(*datasource); + *datasource = NULL; + } return hr; }
@@ -557,7 +565,16 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o
hr = IDBProperties_SetProperties(dbprops, 1, propset); free_dbpropset(1, propset); - TRACE("provider ret 0x%08x\n", hr); + if (FAILED(hr)) + { + ERR("failed to set property, 0x%08x\n", hr); + if (datasource_created) + { + IUnknown_Release(*datasource); + *datasource = NULL; + } + break; + } }
IDBProperties_Release(dbprops); diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c index 9e20fec..c1e440d 100644 --- a/dlls/oledb32/tests/database.c +++ b/dlls/oledb32/tests/database.c @@ -37,6 +37,14 @@ DEFINE_GUID(CSLID_MSDAER, 0xc8b522cf,0x5cf3,0x11ce,0xad,0xe5,0x00,0xaa,0x00,0x44
static WCHAR initstring_default[] = {'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',0};
+#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) +static void _expect_ref(IUnknown* obj, ULONG ref, int line) +{ + ULONG rc = IUnknown_AddRef(obj); + IUnknown_Release(obj); + ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1); +} + static void test_GetDataSource(WCHAR *initstring) { IDataInitialize *datainit = NULL; @@ -48,12 +56,17 @@ static void test_GetDataSource(WCHAR *initstring) hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit); ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_REF(datainit, 1); + /* a failure to create data source here may indicate provider is simply not present */ hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit); if(SUCCEEDED(hr)) { IDBProperties *props = NULL;
+ EXPECT_REF(datainit, 1); + EXPECT_REF(dbinit, 1); + hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBProperties, (void**)&props); ok(hr == S_OK, "got %08x\n", hr); if(SUCCEEDED(hr)) @@ -62,6 +75,8 @@ static void test_GetDataSource(WCHAR *initstring) DBPROPINFOSET *pInfoset; OLECHAR *ary;
+ EXPECT_REF(dbinit, 2); + EXPECT_REF(props, 2); hr = IDBProperties_GetPropertyInfo(props, 0, NULL, &cnt, &pInfoset, &ary); todo_wine ok(hr == S_OK, "got %08x\n", hr); if(hr == S_OK) @@ -80,9 +95,11 @@ static void test_GetDataSource(WCHAR *initstring) IDBProperties_Release(props); }
+ EXPECT_REF(dbinit, 1); IDBInitialize_Release(dbinit); }
+ EXPECT_REF(datainit, 1); IDataInitialize_Release(datainit); }
@@ -186,7 +203,7 @@ static void test_initializationstring(void) static const WCHAR initstring_sqloledb[] = {'P','r','o','v','i','d','e','r','=','S','Q','L','O','L','E','D','B','.','1',';', 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0}; IDataInitialize *datainit = NULL; - IDBInitialize *dbinit = NULL; + IDBInitialize *dbinit; HRESULT hr; WCHAR *initstring = NULL;
@@ -194,10 +211,16 @@ static void test_initializationstring(void) ok(hr == S_OK, "got %08x\n", hr); if(SUCCEEDED(hr)) { + EXPECT_REF(datainit, 1); + + dbinit = NULL; hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring_default, &IID_IDBInitialize, (IUnknown**)&dbinit); if(SUCCEEDED(hr)) { + EXPECT_REF(datainit, 1); + EXPECT_REF(dbinit, 1); + hr = IDataInitialize_GetInitializationString(datainit, (IUnknown*)dbinit, 0, &initstring); ok(hr == S_OK, "got %08x\n", hr); if(hr == S_OK) @@ -210,6 +233,8 @@ static void test_initializationstring(void)
IDBInitialize_Release(dbinit); } + else + ok(dbinit == NULL, "got %p\n", dbinit);
IDataInitialize_Release(datainit); }