From 2a9fae756564fff3ec13922d360031ff2ce8a4e7 Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Tue, 4 Dec 2007 13:22:56 +0000 Subject: [PATCH] rpcrt4: Set the destination pointer in PointerUnmarshall before calling the referenced type's unmarshalling routine. When a pointer that is dereferenced is encountered then this can result in a stale pointer (i.e. the one that is marshalled into the buffer for the embedded pointer unmarshalling case) being used instead of the one that was intended. --- dlls/rpcrt4/ndr_marshall.c | 17 +++++------------ dlls/rpcrt4/tests/server.c | 1 - 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index 84a19909f76..781143a0f79 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c @@ -1020,8 +1020,8 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, * unmarshalling routine for the benefit of the deref code below */ if (!fMustAlloc) { if (pSrcPointer) { - TRACE("pSrcPointer = %p\n", pSrcPointer); - base_ptr_val = pSrcPointer; + TRACE("setting *pPointer to %p\n", pSrcPointer); + *pPointer = base_ptr_val = pSrcPointer; } else fMustAlloc = TRUE; } @@ -1030,11 +1030,9 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, /* the memory in a stub is never initialised, so we have to work out here * whether we have to initialise it so we can use the optimisation of * setting the pointer to the buffer, if possible, or set fMustAlloc to - * TRUE. As there is no space used in the buffer for pointers when using - * reference pointers we must allocate memory in this case */ - if (type == RPC_FC_RP || attr & RPC_FC_P_DEREF) { + * TRUE. */ + if (attr & RPC_FC_P_DEREF) { fMustAlloc = TRUE; - base_ptr_val = NULL; } else { base_ptr_val = NULL; *current_ptr = NULL; @@ -1044,6 +1042,7 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, if (attr & RPC_FC_P_DEREF) { if (fMustAlloc) { base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); + *pPointer = base_ptr_val; current_ptr = (unsigned char **)base_ptr_val; } else current_ptr = *(unsigned char***)current_ptr; @@ -1057,12 +1056,6 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, if (type == RPC_FC_FP) NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id, base_ptr_val); - - /* this must be done after the call to the unmarshaller, since when we are - * unmarshalling reference pointers on the server side *pPointer will be - * pointing to valid data */ - if ((!fMustAlloc || attr & RPC_FC_P_DEREF) && base_ptr_val) - *pPointer = base_ptr_val; } TRACE("pointer=%p\n", *pPointer); diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 538f5a4c774..433657b1336 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -877,7 +877,6 @@ pointer_tests(void) name.name = buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, name.size); get_name(&name); ok(name.name == buffer, "[in,out] pointer should have stayed as %p but instead changed to %p\n", name.name, buffer); - todo_wine ok(!strcmp(name.name, "Jeremy Wh"), "name didn't unmarshall properly, expected \"Jeremy Wh\", but got \"%s\"\n", name.name); HeapFree(GetProcessHeap(), 0, name.name);