Skip to content

Commit

Permalink
Don't pass the managed array object down when clearing a native array…
Browse files Browse the repository at this point in the history
… field. (#33830)

* Don't pass the managed array object down when clearing a native array field.

* Add test.
  • Loading branch information
jkoritzinsky committed Mar 20, 2020
1 parent ada03d7 commit 35df31c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 28 deletions.
8 changes: 3 additions & 5 deletions src/coreclr/src/vm/ilmarshalers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4515,7 +4515,7 @@ void MngdNativeArrayMarshaler::DoClearNativeContents(MngdNativeArrayMarshaler* p

if (pMarshaler != NULL && pMarshaler->ClearOleArray != NULL)
{
pMarshaler->ClearOleArray((BASEARRAYREF*)pManagedHome, *pNativeHome, cElements, pThis->m_pElementMT, pThis->m_pManagedMarshaler);
pMarshaler->ClearOleArray(*pNativeHome, cElements, pThis->m_pElementMT, pThis->m_pManagedMarshaler);
}
}
}
Expand Down Expand Up @@ -4733,15 +4733,13 @@ FCIMPL3(void, MngdFixedArrayMarshaler::ClearNativeContents, MngdFixedArrayMarsha
{
FCALL_CONTRACT;

BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome;

HELPER_METHOD_FRAME_BEGIN_1(arrayRef);
HELPER_METHOD_FRAME_BEGIN_0();

const OleVariant::Marshaler* pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, FALSE);

if (pMarshaler != NULL && pMarshaler->ClearOleArray != NULL)
{
pMarshaler->ClearOleArray(&arrayRef, pNativeHome, pThis->m_cElements, pThis->m_pElementMT, pThis->m_pManagedElementMarshaler);
pMarshaler->ClearOleArray(pNativeHome, pThis->m_cElements, pThis->m_pElementMT, pThis->m_pManagedElementMarshaler);
}

HELPER_METHOD_FRAME_END();
Expand Down
25 changes: 10 additions & 15 deletions src/coreclr/src/vm/olevariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ void OleVariant::MarshalIUnknownArrayComToOle(BASEARRAYREF *pComArray, void *ole
MarshalInterfaceArrayComToOleHelper(pComArray, oleArray, pElementMT, FALSE, cElements);
}

void OleVariant::ClearInterfaceArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearInterfaceArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand Down Expand Up @@ -2009,7 +2009,7 @@ void OleVariant::MarshalBSTRArrayComToOle(BASEARRAYREF *pComArray, void *oleArra
GCPROTECT_END();
}

void OleVariant::ClearBSTRArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearBSTRArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand Down Expand Up @@ -2112,7 +2112,7 @@ void OleVariant::MarshalNonBlittableRecordArrayComToOle(BASEARRAYREF *pComArray,
}
}

void OleVariant::ClearNonBlittableRecordArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearNonBlittableRecordArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand All @@ -2124,20 +2124,15 @@ void OleVariant::ClearNonBlittableRecordArray(BASEARRAYREF* pComArray, void *ole
}
CONTRACTL_END;

ASSERT_PROTECTED(pComArray);

SIZE_T elemSize = pInterfaceMT->GetNativeSize();
SIZE_T componentSize = TypeHandle(pInterfaceMT).MakeSZArray().GetMethodTable()->GetComponentSize();
BYTE *pOle = (BYTE *) oleArray;
BYTE *pOleEnd = pOle + elemSize * cElements;
SIZE_T srcofs = *pComArray != NULL ? ArrayBase::GetDataPtrOffset((*pComArray)->GetMethodTable()) : 0;
while (pOle < pOleEnd)
{
BYTE* managedData = (BYTE*)(*(LPVOID*)pComArray) + srcofs;

MarshalStructViaILStubCode(pManagedMarshalerCode, managedData, pOle, StructMarshalStubs::MarshalOperation::Cleanup);
MarshalStructViaILStubCode(pManagedMarshalerCode, nullptr, pOle, StructMarshalStubs::MarshalOperation::Cleanup);

pOle += elemSize;
srcofs += (*pComArray)->GetComponentSize();
}
}

Expand Down Expand Up @@ -2255,7 +2250,7 @@ void OleVariant::MarshalLPWSTRRArrayComToOle(BASEARRAYREF *pComArray, void *oleA
}
}

void OleVariant::ClearLPWSTRArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearLPWSTRArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand Down Expand Up @@ -2392,7 +2387,7 @@ void OleVariant::MarshalLPSTRRArrayComToOle(BASEARRAYREF *pComArray, void *oleAr
}
}

void OleVariant::ClearLPSTRArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearLPSTRArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand Down Expand Up @@ -2736,7 +2731,7 @@ void OleVariant::MarshalRecordArrayComToOle(BASEARRAYREF *pComArray, void *oleAr
}


void OleVariant::ClearRecordArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pElementMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearRecordArray(void *oleArray, SIZE_T cElements, MethodTable *pElementMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand All @@ -2751,7 +2746,7 @@ void OleVariant::ClearRecordArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_
if (!pElementMT->IsBlittable())
{
_ASSERTE(pElementMT->HasLayout());
ClearNonBlittableRecordArray(pComArray, oleArray, cElements, pElementMT, pManagedMarshalerCode);
ClearNonBlittableRecordArray(oleArray, cElements, pElementMT, pManagedMarshalerCode);
}
}

Expand Down Expand Up @@ -4072,7 +4067,7 @@ void OleVariant::MarshalVariantArrayComToOle(BASEARRAYREF *pComArray, void *oleA
GCPROTECT_END();
}

void OleVariant::ClearVariantArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
void OleVariant::ClearVariantArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode)
{
CONTRACTL
{
Expand Down
16 changes: 8 additions & 8 deletions src/coreclr/src/vm/olevariant.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ class OleVariant
BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar,
BOOL fOleArrayIsValid,SIZE_T cElements,
PCODE pManagedMarshalerCode);
void (*ClearOleArray)(BASEARRAYREF* pComArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);
void (*ClearOleArray)(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);
};

static const Marshaler* GetMarshalerForVarType(VARTYPE vt, BOOL fThrow);
Expand Down Expand Up @@ -521,7 +521,7 @@ class OleVariant
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearBSTRArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);
static void ClearBSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);
#endif // FEATURE_COMINTEROP

static void MarshalNonBlittableRecordArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
Expand All @@ -530,7 +530,7 @@ class OleVariant
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearNonBlittableRecordArray(BASEARRAYREF* comArray, void* oleArray,
static void ClearNonBlittableRecordArray(void* oleArray,
SIZE_T cElements, MethodTable* pInterfaceMT,
PCODE pManagedMarshalerCode);

Expand All @@ -540,7 +540,7 @@ class OleVariant
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearLPWSTRArray(BASEARRAYREF* comArray, void* oleArray,
static void ClearLPWSTRArray(void* oleArray,
SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);

static void MarshalLPSTRArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
Expand All @@ -549,7 +549,7 @@ class OleVariant
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearLPSTRArray(BASEARRAYREF* comArray, void* oleArray,
static void ClearLPSTRArray(void* oleArray,
SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);

static void MarshalDateArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
Expand All @@ -564,7 +564,7 @@ class OleVariant
BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar,
BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearRecordArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pElementMT, PCODE pManagedMarshalerCode);
static void ClearRecordArray(void* oleArray, SIZE_T cElements, MethodTable* pElementMT, PCODE pManagedMarshalerCode);

#ifdef FEATURE_COMINTEROP
static HRESULT MarshalCommonOleRefVariantForObject(OBJECTREF *pObj, VARIANT *pOle);
Expand All @@ -574,7 +574,7 @@ class OleVariant
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearInterfaceArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);
static void ClearInterfaceArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);

static void MarshalBoolVariantOleToCom(VARIANT* pOleVariant, VariantData* pComVariant);

Expand Down Expand Up @@ -623,7 +623,7 @@ class OleVariant
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
SIZE_T cElements, PCODE pManagedMarshalerCode);
static void ClearVariantArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);
static void ClearVariantArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode);

#ifdef FEATURE_CLASSIC_COMINTEROP
static void MarshalArrayVariantOleToCom(VARIANT* pOleVariant, VariantData* pComVariant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ public void DestroyStructure_AutoLayout_ThrowsArgumentException()
AssertExtensions.Throws<ArgumentException>("structureType", () => Marshal.DestroyStructure((IntPtr)1, typeof(AutoLayoutStruct)));
}

[Fact]
public void DestroyStructure_NestedNonBlittableStruct_Success()
{
WINTRUST_BLOB_INFO wbi = new WINTRUST_BLOB_INFO();
byte[] contentBytes = System.Text.Encoding.Unicode.GetBytes("foo");

wbi.gSubject.Data1 = 0x603bcc1f;
wbi.gSubject.Data2 = 0x4b59;
wbi.gSubject.Data3 = 0x4e08;
wbi.gSubject.Data4 = new byte[] { 0xb7, 0x24, 0xd2, 0xc6, 0x29, 0x7e, 0xf3, 0x51 };

wbi.cbStruct = (uint)Marshal.SizeOf(wbi);
wbi.pcwszDisplayName = "bar";

IntPtr pBlob = Marshal.AllocCoTaskMem(Marshal.SizeOf(wbi));
Marshal.StructureToPtr(wbi, pBlob, false);

Marshal.DestroyStructure<WINTRUST_BLOB_INFO>(pBlob);

Marshal.FreeCoTaskMem(pBlob);
}

[StructLayout(LayoutKind.Sequential)]
public struct TestStruct
{
Expand All @@ -118,5 +140,30 @@ public struct AutoLayoutStruct
{
public int i;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct GUID
{
internal uint Data1;
internal ushort Data2;
internal ushort Data3;

/// unsigned char[8]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
internal byte[] Data4;
}
[StructLayout(LayoutKind.Sequential)]
internal struct WINTRUST_BLOB_INFO
{
internal uint cbStruct;

/// GUID->_GUID
internal GUID gSubject;
//[MarshalAs(UnmanagedType.Struct)]
//internal Guid gSubject;

[MarshalAsAttribute(UnmanagedType.LPWStr)]
internal string pcwszDisplayName;
}
}
}

0 comments on commit 35df31c

Please sign in to comment.