Commit 2a9fae75 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

rpcrt4: Set the destination pointer in PointerUnmarshall before calling the…

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.
parent b12ebbda
...@@ -1020,8 +1020,8 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -1020,8 +1020,8 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
* unmarshalling routine for the benefit of the deref code below */ * unmarshalling routine for the benefit of the deref code below */
if (!fMustAlloc) { if (!fMustAlloc) {
if (pSrcPointer) { if (pSrcPointer) {
TRACE("pSrcPointer = %p\n", pSrcPointer); TRACE("setting *pPointer to %p\n", pSrcPointer);
base_ptr_val = pSrcPointer; *pPointer = base_ptr_val = pSrcPointer;
} else } else
fMustAlloc = TRUE; fMustAlloc = TRUE;
} }
...@@ -1030,11 +1030,9 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -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 /* 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 * 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 * 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 * TRUE. */
* reference pointers we must allocate memory in this case */ if (attr & RPC_FC_P_DEREF) {
if (type == RPC_FC_RP || attr & RPC_FC_P_DEREF) {
fMustAlloc = TRUE; fMustAlloc = TRUE;
base_ptr_val = NULL;
} else { } else {
base_ptr_val = NULL; base_ptr_val = NULL;
*current_ptr = NULL; *current_ptr = NULL;
...@@ -1044,6 +1042,7 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -1044,6 +1042,7 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if (attr & RPC_FC_P_DEREF) { if (attr & RPC_FC_P_DEREF) {
if (fMustAlloc) { if (fMustAlloc) {
base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
*pPointer = base_ptr_val;
current_ptr = (unsigned char **)base_ptr_val; current_ptr = (unsigned char **)base_ptr_val;
} else } else
current_ptr = *(unsigned char***)current_ptr; current_ptr = *(unsigned char***)current_ptr;
...@@ -1057,12 +1056,6 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -1057,12 +1056,6 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if (type == RPC_FC_FP) if (type == RPC_FC_FP)
NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id, NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
base_ptr_val); 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); TRACE("pointer=%p\n", *pPointer);
......
...@@ -877,7 +877,6 @@ pointer_tests(void) ...@@ -877,7 +877,6 @@ pointer_tests(void)
name.name = buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, name.size); name.name = buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, name.size);
get_name(&name); get_name(&name);
ok(name.name == buffer, "[in,out] pointer should have stayed as %p but instead changed to %p\n", name.name, buffer); 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); 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); HeapFree(GetProcessHeap(), 0, name.name);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment