[PATCH 2/2] rpcrt4: Avoid reference leaks when unmarshalling [in, out] interface pointers.

Zebediah Figura z.figura12 at gmail.com
Tue Oct 30 18:28:53 CDT 2018


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/rpcrt4/ndr_ole.c            | 10 ++++++++--
 dlls/rpcrt4/tests/ndr_marshall.c |  2 --
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/dlls/rpcrt4/ndr_ole.c b/dlls/rpcrt4/ndr_ole.c
index 8608691231..c8026c0ff1 100644
--- a/dlls/rpcrt4/ndr_ole.c
+++ b/dlls/rpcrt4/ndr_ole.c
@@ -338,19 +338,25 @@ unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
                                                     PFORMAT_STRING pFormat,
                                                     unsigned char fMustAlloc)
 {
+  IUnknown **unk = (IUnknown **)ppMemory;
   LPSTREAM stream;
   HRESULT hr;
 
   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
   if (!LoadCOM()) return NULL;
-  *(LPVOID*)ppMemory = NULL;
+
+  /* Avoid reference leaks for [in, out] pointers. */
+  if (pStubMsg->IsClient && *unk)
+    IUnknown_Release(*unk);
+
+  *unk = NULL;
   if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
     ULONG size;
 
     hr = RpcStream_Create(pStubMsg, FALSE, &size, &stream);
     if (hr == S_OK) {
       if (size != 0)
-        hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
+        hr = COM_UnmarshalInterface(stream, &IID_NULL, (void **)unk);
 
       IStream_Release(stream);
     }
diff --git a/dlls/rpcrt4/tests/ndr_marshall.c b/dlls/rpcrt4/tests/ndr_marshall.c
index 5da03e2ef7..d436b42648 100644
--- a/dlls/rpcrt4/tests/ndr_marshall.c
+++ b/dlls/rpcrt4/tests/ndr_marshall.c
@@ -1327,9 +1327,7 @@ static void test_iface_ptr(void)
     ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
     ok(!my_free_called, "free called %d\n", my_free_called);
     ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
-todo_wine
     ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
-client_obj.ref = 1;
 
     hr = IPersist_GetClassID(proxy, &clsid);
     ok(hr == S_OK, "got hr %#x\n", hr);
-- 
2.19.1




More information about the wine-devel mailing list