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:
parent
b12ebbdaca
commit
2a9fae7565
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue