From bd540938a4830ee91dec5ee2d39545b2f69a19d5 Mon Sep 17 00:00:00 2001 From: Giridhar Trivedi Date: Wed, 8 Feb 2023 22:15:44 +0530 Subject: [PATCH] Handle crash when [out] parameter of type int is passed to delegate (#81276) When a delegate is passed an [out] parameter of type "int" it will crash since this data type is not handled in emit_managed_wrapper_ilgen. This will lead to a crash. With this fix [out] parameter of type "int" is handled after adding an addition case statement to handle MONO_TYPE_I in emit_managed_wrapper_ilgen. Supporting UT is added. Co-authored-by: Giridhar Trivedi --- src/mono/mono/metadata/marshal-lightweight.c | 1 + .../MarshalAPI/FunctionPointer/FunctionPointer.cs | 25 ++++++++++++++++++++++ .../FunctionPointer/FunctionPointerNative.cpp | 6 ++++++ 3 files changed, 32 insertions(+) diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 2b8c321..eff038a 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -2630,6 +2630,7 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s case MONO_TYPE_CLASS: case MONO_TYPE_VALUETYPE: case MONO_TYPE_PTR: + case MONO_TYPE_I: mono_emit_marshal (m, i, invoke_sig->params [i], mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT); break; default: diff --git a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs index b920b91..e8d4e72 100644 --- a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs +++ b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs @@ -16,6 +16,9 @@ public partial class FunctionPtr [DllImport(nameof(FunctionPointerNative))] static unsafe extern void FillOutPtr(IntPtr* p); + + [DllImport(nameof(FunctionPointerNative))] + static unsafe extern void FillOutIntParameter(out IntPtr p); } delegate void VoidDelegate(); @@ -81,6 +84,27 @@ public partial class FunctionPtr Assert.Equal(expectedValue, outVar); } + [DllImport(nameof(FunctionPointerNative))] + static unsafe extern void FillOutIntParameter(out IntPtr p); + + private unsafe delegate void DelegateToFillOutIntParameter(out IntPtr p); + + public static void RunGetDelForOutIntTest() + { + Console.WriteLine($"Running {nameof(RunGetDelForOutIntTest)}..."); + IntPtr outVar = 0; + int expectedValue = 50; + unsafe + { + DelegateToFillOutIntParameter d = new DelegateToFillOutIntParameter(FillOutIntParameter); + IntPtr ptr = Marshal.GetFunctionPointerForDelegate(d); + DelegateToFillOutIntParameter OutPtrDelegate = Marshal.GetDelegateForFunctionPointer(ptr); + OutPtrDelegate(out outVar); + GC.KeepAlive(d); + } + Assert.Equal(expectedValue, outVar); + } + public static int Main() { try @@ -88,6 +112,7 @@ public partial class FunctionPtr RunGetDelForFcnPtrTest(); RunGetFcnPtrSingleMulticastTest(); RunGetDelForOutPtrTest(); + RunGetDelForOutIntTest(); } catch (Exception e) { diff --git a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp index 9056f9a..e19d5f1 100644 --- a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp +++ b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp @@ -35,3 +35,9 @@ extern "C" DLL_EXPORT void FillOutPtr(intptr_t *p) { *p = 60; } + +extern "C" DLL_EXPORT void FillOutIntParameter(intptr_t *p) +{ + *p = 50; +} + -- 2.7.4