[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