[PATCH 1/3] ole32: Add VT_ARRAY support to PropVariant.

Sven Baars sven.wine at gmail.com
Thu May 30 04:39:33 CDT 2019


Signed-off-by: Sven Baars <sven.wine at gmail.com>
---
This should fix some memory leaks where PropVariantClear is expected to
destroy the safearray.

 dlls/ole32/ole2.c              | 26 ++++++++++++++
 dlls/ole32/tests/propvariant.c | 63 ++++++++++++++++++++++++----------
 2 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c
index 2de9edbb80..fa39abe2de 100644
--- a/dlls/ole32/ole2.c
+++ b/dlls/ole32/ole2.c
@@ -2797,6 +2797,25 @@ static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt)
     case VT_FILETIME|VT_VECTOR:
     case VT_CF|VT_VECTOR:
     case VT_CLSID|VT_VECTOR:
+    case VT_ARRAY|VT_I1:
+    case VT_ARRAY|VT_UI1:
+    case VT_ARRAY|VT_I2:
+    case VT_ARRAY|VT_UI2:
+    case VT_ARRAY|VT_I4:
+    case VT_ARRAY|VT_UI4:
+    case VT_ARRAY|VT_INT:
+    case VT_ARRAY|VT_UINT:
+    case VT_ARRAY|VT_R4:
+    case VT_ARRAY|VT_R8:
+    case VT_ARRAY|VT_CY:
+    case VT_ARRAY|VT_DATE:
+    case VT_ARRAY|VT_BSTR:
+    case VT_ARRAY|VT_BOOL:
+    case VT_ARRAY|VT_DECIMAL:
+    case VT_ARRAY|VT_DISPATCH:
+    case VT_ARRAY|VT_UNKNOWN:
+    case VT_ARRAY|VT_ERROR:
+    case VT_ARRAY|VT_VARIANT:
         return S_OK;
     }
     WARN("Bad type %d\n", vt);
@@ -2908,6 +2927,8 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
                 CoTaskMemFree(pvar->u.capropvar.pElems);
             }
         }
+        else if (pvar->vt & VT_ARRAY)
+            hr = SafeArrayDestroy(pvar->u.parray);
         else
         {
             WARN("Invalid/unsupported type %d\n", pvar->vt);
@@ -3088,6 +3109,11 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest,      /* [out] */
             else
                 CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
         }
+        else if (pvarSrc->vt & VT_ARRAY)
+        {
+            pvarDest->u.uhVal.QuadPart = 0;
+            return SafeArrayCopy(pvarSrc->u.parray, &pvarDest->u.parray);
+        }
         else
             WARN("Invalid/unsupported type %d\n", pvarSrc->vt);
     }
diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c
index 8c9f79e8d6..18ecfa6528 100644
--- a/dlls/ole32/tests/propvariant.c
+++ b/dlls/ole32/tests/propvariant.c
@@ -46,28 +46,28 @@ static const struct valid_mapping
 {
     { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_EMPTY */
     { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_NULL */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_I2 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_I4 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_R4 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_R8 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_CY */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_DATE */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_BSTR */
-    { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_DISPATCH */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_ERROR */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_BOOL */
-    { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_VARIANT */
-    { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_UNKNOWN */
-    { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_DECIMAL */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_I2 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_I4 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_R4 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_R8 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_CY */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_DATE */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_BSTR */
+    { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_DISPATCH */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_ERROR */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_BOOL */
+    { PROP_V1 | PROP_TODO , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_VARIANT */
+    { PROP_V1 , PROP_V1, PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_UNKNOWN */
+    { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_DECIMAL */
     { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 15 */
-    { PROP_V1 , PROP_V1 | PROP_TODO , PROP_V1 , PROP_V1 | PROP_TODO  }, /* VT_I1 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_UI1 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_UI2 */
-    { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_UI4 */
+    { PROP_V1 , PROP_V1 , PROP_V1 , PROP_V1 | PROP_TODO  }, /* VT_I1 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_UI1 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_UI2 */
+    { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO  }, /* VT_UI4 */
     { PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_I8 */
     { PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_UI8 */
-    { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_INT */
-    { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_UINT */
+    { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_INT */
+    { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO  }, /* VT_UINT */
     { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_VOID */
     { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_HRESULT */
     { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_PTR */
@@ -351,6 +351,9 @@ static void test_copy(void)
     struct unk_impl unk_obj = {{&unk_vtbl}, 1};
     PROPVARIANT propvarSrc;
     PROPVARIANT propvarDst;
+    SAFEARRAY *sa;
+    SAFEARRAYBOUND sabound;
+    LONG saindex;
     HRESULT hr;
 
     propvarSrc.vt = VT_BSTR;
@@ -392,6 +395,28 @@ static void test_copy(void)
     ok(hr == S_OK, "PropVariantClear(...VT_UNKNOWN...) failed: 0x%08x.\n", hr);
     ok(unk_obj.ref == 1, "got wrong refcount: %d.\n", unk_obj.ref);
     memset(&propvarSrc, 0, sizeof(propvarSrc));
+
+    sabound.lLbound = 0;
+    sabound.cElements = 2;
+    sa = SafeArrayCreate(VT_UNKNOWN, 1, &sabound);
+    saindex = 0;
+    SafeArrayPutElement(sa, &saindex, &unk_obj.IUnknown_iface);
+    saindex = 1;
+    SafeArrayPutElement(sa, &saindex, &unk_obj.IUnknown_iface);
+    ok(unk_obj.ref == 3, "got wrong refcount: %d.\n", unk_obj.ref);
+
+    propvarSrc.vt = VT_ARRAY | VT_UNKNOWN;
+    U(propvarSrc).parray = sa;
+    hr = PropVariantCopy(&propvarDst, &propvarSrc);
+    ok(hr == S_OK, "PropVariantCopy(...VT_ARRAY|VT_UNKNOWN...) failed: 0x%08x.\n", hr);
+    ok(unk_obj.ref == 5, "got wrong refcount: %d.\n", unk_obj.ref);
+    hr = PropVariantClear(&propvarDst);
+    ok(hr == S_OK, "PropVariantClear(...VT_ARRAY|VT_UNKNOWN...) failed: 0x%08x.\n", hr);
+    ok(unk_obj.ref == 3, "got wrong refcount: %d.\n", unk_obj.ref);
+    hr = PropVariantClear(&propvarSrc);
+    ok(hr == S_OK, "PropVariantClear(...VT_ARRAY|VT_UNKNOWN...) failed: 0x%08x.\n", hr);
+    ok(unk_obj.ref == 1, "got wrong refcount: %d.\n", unk_obj.ref);
+    memset(&propvarSrc, 0, sizeof(propvarSrc));
 }
 
 struct _PMemoryAllocator_vtable {
-- 
2.17.1




More information about the wine-devel mailing list