Update comment and add test for Marshal.GetDelegateForFunctionPointer (#48362)
authorJan Kotas <jkotas@microsoft.com>
Wed, 17 Feb 2021 07:38:54 +0000 (23:38 -0800)
committerGitHub <noreply@github.com>
Wed, 17 Feb 2021 07:38:54 +0000 (23:38 -0800)
* Update comment and fix test for Marshal.GetDelegateForFunctionPointer argument validation

* Disable test on Mono

src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetDelegateForFunctionPointerTests.cs

index 9f8cc4c..3c247a1 100644 (file)
@@ -867,11 +867,10 @@ namespace System.Runtime.InteropServices
                 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
             }
 
-            // COMPAT: This block of code isn't entirely correct.
-            // Users passing in typeof(MulticastDelegate) as 't' skip this check
-            // since Delegate is a base type of MulticastDelegate.
-            Type? c = t.BaseType;
-            if (c != typeof(Delegate) && c != typeof(MulticastDelegate))
+            // For backward compatibility, we allow lookup up of existing delegate to
+            // function pointer mappings using abstract MulticastDelegate type. We will check
+            // for the non-abstract delegate type later if no existing mapping is found.
+            if (t.BaseType != typeof(MulticastDelegate) && t != typeof(MulticastDelegate))
             {
                 throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t));
             }
index 6f12389..c11c755 100644 (file)
@@ -75,6 +75,16 @@ namespace System.Runtime.InteropServices.Tests
             VerifyDelegate(functionDelegate, targetMethod);
         }
 
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/48379", TestRuntimes.Mono)]
+        public void GetDelegateForFunctionPointer_MulticastDelegate_ThrowsMustBeDelegate()
+        {
+            IntPtr ptr = Marshal.AllocHGlobal(16);
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetDelegateForFunctionPointer(ptr, typeof(MulticastDelegate)));
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetDelegateForFunctionPointer<MulticastDelegate>(ptr));
+            Marshal.FreeHGlobal(ptr);
+        }
+
         private static void VerifyDelegate(Delegate d, MethodInfo expectedMethod)
         {
             Assert.IsType<NonGenericDelegate>(d);