From a77f12c74bea2882e9c47e5100bd590086702d75 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Fri, 3 Apr 2020 20:05:10 -0700 Subject: [PATCH] Memory leak during marshal failure. Minor code cleanup to make the logic clearer. --- .../src/System/StubHelpers.cs | 15 +++++++++++++-- src/coreclr/src/vm/olevariant.cpp | 7 ++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/StubHelpers.cs index 691113f665be0..81c1611be4f56 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/StubHelpers.cs @@ -67,15 +67,26 @@ internal static unsafe IntPtr ConvertToNative(int flags, string strManaged, IntP // + 1 for the null character from the user. + 1 for the null character we put in. nb = checked((strManaged.Length + 1) * Marshal.SystemMaxDBCSCharSize + 1); + bool didAlloc = false; + // Use the pre-allocated buffer (allocated by localloc IL instruction) if not NULL, // otherwise fallback to AllocCoTaskMem if (pbNativeBuffer == null) { pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb); + didAlloc = true; } - nb = Marshal.StringToAnsiString(strManaged, pbNativeBuffer, nb, - bestFit: 0 != (flags & 0xFF), throwOnUnmappableChar: 0 != (flags >> 8)); + try + { + nb = Marshal.StringToAnsiString(strManaged, pbNativeBuffer, nb, + bestFit: 0 != (flags & 0xFF), throwOnUnmappableChar: 0 != (flags >> 8)); + } + catch (Exception) when (didAlloc) + { + Marshal.FreeCoTaskMem((IntPtr)pbNativeBuffer); + throw; + } } else { diff --git a/src/coreclr/src/vm/olevariant.cpp b/src/coreclr/src/vm/olevariant.cpp index 240b56427f761..fc0ab0704ec68 100644 --- a/src/coreclr/src/vm/olevariant.cpp +++ b/src/coreclr/src/vm/olevariant.cpp @@ -2101,14 +2101,15 @@ void OleVariant::MarshalNonBlittableRecordArrayComToOle(BASEARRAYREF *pComArray, FillMemory(pOle, pOleEnd - pOle, 0); } - SIZE_T srcofs = ArrayBase::GetDataPtrOffset( (*pComArray)->GetMethodTable() ); + const SIZE_T compSize = (*pComArray)->GetComponentSize(); + SIZE_T offset = 0; while (pOle < pOleEnd) { - BYTE* managedData = (BYTE*)(*(LPVOID*)pComArray) + srcofs; + BYTE* managedData = (*pComArray)->GetDataPtr() + offset; MarshalStructViaILStubCode(pManagedMarshalerCode, managedData, pOle, StructMarshalStubs::MarshalOperation::Marshal); pOle += elemSize; - srcofs += (*pComArray)->GetComponentSize(); + offset += compSize; } }