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.
This commit is contained in:
Rob Shearman 2007-12-04 13:22:56 +00:00 committed by Alexandre Julliard
parent b12ebbdaca
commit 2a9fae7565
2 changed files with 5 additions and 13 deletions

View File

@ -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);

View File

@ -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);