Commit 6d7572c0 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

oleaut32: Unmarshall byref types correctly in IDispatch_Invoke_Proxy.

Byref arguments should only be passed in the rgVarRef array, not in arg array. Copy the value into the rgVarRef array before calling the remote function to ensure that memory isn't allocated for the byref pointers during unmarshalling.
parent b60e9819
......@@ -1364,7 +1364,6 @@ static void test_typelibmarshal(void)
ok_ole_success(hr, ITypeInfo_Invoke);
ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
ok(V_VT(&vararg[0]) == (VT_UI4|VT_BYREF), "arg VT not unmarshalled correctly: %x\n", V_VT(&vararg[0]));
todo_wine
ok(V_UI4REF(&vararg[0]) == &uval, "Byref pointer not preserved: %p/%p\n", &uval, V_UI4REF(&vararg[0]));
ok(*V_UI4REF(&vararg[0]) == 42, "Expected 42 to be returned instead of %u\n", *V_UI4REF(&vararg[0]));
VariantClear(&varresult);
......
......@@ -1180,6 +1180,8 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
if (V_ISBYREF(arg)) {
rgVarRefIdx[cVarRef] = u;
VariantInit(&rgVarRef[cVarRef]);
VariantCopy(&rgVarRef[cVarRef], arg);
VariantClear(arg);
cVarRef++;
}
}
......@@ -1265,6 +1267,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
}
if (SUCCEEDED(hr)) {
/* copy ref args to arg array */
for (u=0; u<cVarRef; u++) {
unsigned i = rgVarRefIdx[u];
VariantCopy(&arg[i], &rgVarRef[u]);
}
pDispParams->rgvarg = arg;
hr = IDispatch_Invoke(This,
......@@ -1277,14 +1285,10 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
pExcepInfo,
pArgErr);
/* copy ref args to out list */
/* copy ref args from arg array */
for (u=0; u<cVarRef; u++) {
unsigned i = rgVarRefIdx[u];
VariantInit(&rgVarRef[u]);
VariantCopy(&rgVarRef[u], &arg[i]);
/* clear original if equal, to avoid double-free */
if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
VariantClear(&rgvarg[i]);
}
}
......
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