From 6592c25bc749373cad0e7584ef13e010b4a2431d Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Tue, 24 Nov 2009 14:06:57 +0000 Subject: [PATCH] ole32: Fix circular reference count in default handler objects. This is caused by caching a pointer and reference to the data cache's IPersistStorage interface without managing reference counts appropriately. --- dlls/ole32/defaulthandler.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dlls/ole32/defaulthandler.c b/dlls/ole32/defaulthandler.c index a3da0dd201..5130513d57 100644 --- a/dlls/ole32/defaulthandler.c +++ b/dlls/ole32/defaulthandler.c @@ -1960,9 +1960,21 @@ static DefaultHandler* DefaultHandler_Construct( &IID_IUnknown, (void**)&This->dataCache); if(SUCCEEDED(hr)) + { hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg); + /* keeping a reference to This->dataCache_PersistStg causes us to keep a + * reference on the outer object */ + if (SUCCEEDED(hr)) + IUnknown_Release(This->outerUnknown); + else + IUnknown_Release(This->dataCache); + } if(FAILED(hr)) + { ERR("Unexpected error creating data cache\n"); + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } This->clsid = *clsid; This->clientSite = NULL; @@ -2009,6 +2021,13 @@ static DefaultHandler* DefaultHandler_Construct( static void DefaultHandler_Destroy( DefaultHandler* This) { + TRACE("(%p)\n", This); + + /* AddRef/Release may be called on this object during destruction. + * Prevent the object being destroyed recursively by artificially raising + * the reference count. */ + This->ref = 10000; + /* release delegates */ DefaultHandler_Stop(This); release_delegates(This); @@ -2020,6 +2039,9 @@ static void DefaultHandler_Destroy( if (This->dataCache) { + /* to balance out the release of dataCache_PersistStg which will result + * in a reference being released from the outer unknown */ + IUnknown_AddRef(This->outerUnknown); IPersistStorage_Release(This->dataCache_PersistStg); IUnknown_Release(This->dataCache); This->dataCache_PersistStg = NULL; -- 2.32.0.93.g670b81a890