Signed-off-by: Sven Baars sven.wine@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 {
Signed-off-by: Sven Baars sven.wine@gmail.com --- dlls/propsys/tests/propsys.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 1be88172bd..22117b5805 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -1525,13 +1525,14 @@ static void test_PropVariantToBuffer(void) hr = SafeArrayAccessData(sa, &pdata); ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); memcpy(pdata, data, sizeof(data)); + hr = SafeArrayUnaccessData(sa); + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); U(propvar).parray = sa; buffer[0] = 99; hr = PropVariantToBuffer(&propvar, buffer, 11); todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); ok(buffer[0] == 99, "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); - SafeArrayDestroy(sa); PropVariantClear(&propvar);
PropVariantInit(&propvar); @@ -1544,12 +1545,13 @@ static void test_PropVariantToBuffer(void) hr = SafeArrayAccessData(sa, &pdata); ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); memcpy(pdata, data, sizeof(data)); + hr = SafeArrayUnaccessData(sa); + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); U(propvar).parray = sa; hr = PropVariantToBuffer(&propvar, buffer, sizeof(data)); todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); todo_wine ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); - SafeArrayDestroy(sa); PropVariantClear(&propvar);
PropVariantInit(&propvar); @@ -1571,10 +1573,11 @@ static void test_PropVariantToBuffer(void) hr = SafeArrayAccessData(sa, &pdata); ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); memcpy(pdata, data_int8, sizeof(data_int8)); + hr = SafeArrayUnaccessData(sa); + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); U(propvar).parray = sa; hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); - SafeArrayDestroy(sa); PropVariantClear(&propvar); }
Signed-off-by: Sven Baars sven.wine@gmail.com --- dlls/propsys/tests/propsys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 22117b5805..77ffe05f6d 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -1485,13 +1485,13 @@ static void test_PropVariantToBuffer(void) UINT8 buffer[256];
hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); hr = PropVariantToBuffer(&propvar, NULL, 0); /* crash when cb isn't zero */ ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); PropVariantClear(&propvar);
hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); hr = PropVariantToBuffer(&propvar, buffer, 10); ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); @@ -1499,7 +1499,7 @@ static void test_PropVariantToBuffer(void) PropVariantClear(&propvar);
hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); buffer[0] = 99; hr = PropVariantToBuffer(&propvar, buffer, 11); ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); @@ -1508,7 +1508,7 @@ static void test_PropVariantToBuffer(void) PropVariantClear(&propvar);
hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); hr = PropVariantToBuffer(&propvar, buffer, 9); ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); ok(!memcmp(buffer, data, 9) && !buffer[9], "got wrong buffer.\n");