Don't trash the dst variant if we can't do the type conversion.

Add a test for this.
This commit is contained in:
Huw Davies 2004-09-22 19:12:18 +00:00 committed by Alexandre Julliard
parent 634c7a49c4
commit 76c5590bfb
2 changed files with 39 additions and 10 deletions

View File

@ -5304,6 +5304,30 @@ static void test_NullByRef()
ok(hRes == DISP_E_BADVARTYPE, "VariantChangeTypeEx should return DISP_E_BADVARTYPE\n");
}
/* Dst Variant should remain unchanged if VariantChangeType cannot convert */
static void test_ChangeType_keep_dst()
{
VARIANT v1, v2;
BSTR bstr;
WCHAR testW[] = {'t','e','s','t',0};
HRESULT hres;
bstr = SysAllocString(testW);
VariantClear(&v1);
VariantClear(&v2);
V_VT(&v1) = VT_BSTR;
V_BSTR(&v1) = bstr;
hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08lx\n", hres);
ok(V_VT(&v1) == VT_BSTR && V_BSTR(&v1) == bstr, "VariantChangeTypeEx changed dst variant\n");
V_VT(&v2) = VT_INT;
V_INT(&v2) = 4;
hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08lx\n", hres);
ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");
SysFreeString(bstr);
}
START_TEST(vartype)
{
hOleaut32 = LoadLibraryA("oleaut32.dll");
@ -5594,4 +5618,5 @@ START_TEST(vartype)
test_ClearCustData();
test_NullByRef();
test_ChangeType_keep_dst();
}

View File

@ -982,31 +982,35 @@ HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
if (SUCCEEDED(res))
{
VARIANTARG vTmp;
VARIANTARG vTmp, vSrcDeref;
if(V_VT(pvargSrc)&VT_BYREF && !V_BYREF(pvargSrc))
res = DISP_E_TYPEMISMATCH;
else
{
V_VT(&vTmp) = VT_EMPTY;
res = VariantCopyInd(&vTmp, pvargSrc);
V_VT(&vSrcDeref) = VT_EMPTY;
VariantClear(&vTmp);
VariantClear(&vSrcDeref);
}
if (SUCCEEDED(res))
{
res = VariantClear(pvargDest);
res = VariantCopyInd(&vSrcDeref, pvargSrc);
if (SUCCEEDED(res))
{
if (V_ISARRAY(&vTmp) || (vt & VT_ARRAY))
res = VARIANT_CoerceArray(pvargDest, &vTmp, vt);
if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY))
res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt);
else
res = VARIANT_Coerce(pvargDest, lcid, wFlags, &vTmp, vt);
res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt);
if (SUCCEEDED(res))
V_VT(pvargDest) = vt;
if (SUCCEEDED(res)) {
V_VT(&vTmp) = vt;
VariantCopy(pvargDest, &vTmp);
}
VariantClear(&vTmp);
VariantClear(&vSrcDeref);
}
VariantClear(&vTmp);
}
}
}