variant: VariantChangeType shouldn't trash dst variant
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Wed Sep 22 06:23:11 CDT 2004
Huw Davies <huw at codeweavers.com>
Don't trash the dst variant if we can't do the type
conversion.
Add a test for this.
--
Huw Davies
huw at codeweavers.com
Index: dlls/oleaut32/variant.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v
retrieving revision 1.101
diff -u -r1.101 variant.c
--- dlls/oleaut32/variant.c 25 Aug 2004 00:38:59 -0000 1.101
+++ dlls/oleaut32/variant.c 22 Sep 2004 11:17:28 -0000
@@ -982,31 +982,35 @@
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);
}
}
}
Index: dlls/oleaut32/tests/vartype.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/tests/vartype.c,v
retrieving revision 1.18
diff -u -r1.18 vartype.c
--- dlls/oleaut32/tests/vartype.c 16 Sep 2004 19:08:23 -0000 1.18
+++ dlls/oleaut32/tests/vartype.c 22 Sep 2004 11:17:28 -0000
@@ -5304,6 +5304,30 @@
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 @@
test_ClearCustData();
test_NullByRef();
+ test_ChangeType_keep_dst();
}
More information about the wine-patches
mailing list