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