From 5d9f76f4815f8c2c178b76f1bc6644363d6df2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Bourbonnais?= Date: Thu, 17 Dec 2020 13:17:17 -0500 Subject: [PATCH 1/2] Fix illegal delegate usage Cache the delegates to native code we've created so that when we need to call that delegate, we don't ask for a delegate from a native pointer (that is a delegate to managed code.) --- src/runtime/interop.cs | 4 ++++ src/runtime/managedtype.cs | 7 ++++--- src/runtime/nativecall.cs | 11 ++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/runtime/interop.cs b/src/runtime/interop.cs index 10b6ee476..ff9a98622 100644 --- a/src/runtime/interop.cs +++ b/src/runtime/interop.cs @@ -491,6 +491,9 @@ internal static Type GetPrototype(string name) return pmap[name] as Type; } + + internal static Dictionary allocatedThunks = new Dictionary(); + internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null) { Type dt; @@ -505,6 +508,7 @@ internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null) } Delegate d = Delegate.CreateDelegate(dt, method); var info = new ThunkInfo(d); + allocatedThunks[info.Address] = d; return info; } diff --git a/src/runtime/managedtype.cs b/src/runtime/managedtype.cs index 87a89b00a..b4baef835 100644 --- a/src/runtime/managedtype.cs +++ b/src/runtime/managedtype.cs @@ -178,7 +178,7 @@ internal static int PyVisit(IntPtr ob, IntPtr visit, IntPtr arg) { return 0; } - var visitFunc = (Interop.ObjObjFunc)Marshal.GetDelegateForFunctionPointer(visit, typeof(Interop.ObjObjFunc)); + var visitFunc = NativeCall.GetDelegate(visit); return visitFunc(ob, arg); } @@ -196,7 +196,7 @@ internal void CallTypeClear() { return; } - var clearFunc = (Interop.InquiryFunc)Marshal.GetDelegateForFunctionPointer(clearPtr, typeof(Interop.InquiryFunc)); + var clearFunc = NativeCall.GetDelegate(clearPtr); clearFunc(pyHandle); } @@ -214,7 +214,8 @@ internal void CallTypeTraverse(Interop.ObjObjFunc visitproc, IntPtr arg) { return; } - var traverseFunc = (Interop.ObjObjArgFunc)Marshal.GetDelegateForFunctionPointer(traversePtr, typeof(Interop.ObjObjArgFunc)); + var traverseFunc = NativeCall.GetDelegate(traversePtr); + var visiPtr = Marshal.GetFunctionPointerForDelegate(visitproc); traverseFunc(pyHandle, visiPtr, arg); } diff --git a/src/runtime/nativecall.cs b/src/runtime/nativecall.cs index e33eb1c81..8bd5a15f2 100644 --- a/src/runtime/nativecall.cs +++ b/src/runtime/nativecall.cs @@ -40,10 +40,15 @@ public static int Int_Call_3(IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3) return d(a1, a2, a3); } - private static T GetDelegate(IntPtr fp) where T: Delegate + internal static T GetDelegate(IntPtr fp) where T: Delegate { - // Use Marshal.GetDelegateForFunctionPointer<> directly after upgrade the framework - return (T)Marshal.GetDelegateForFunctionPointer(fp, typeof(T)); + Delegate d = null; + if (!Interop.allocatedThunks.TryGetValue(fp, out d)) + { + // Use Marshal.GetDelegateForFunctionPointer<> directly after upgrade the framework + d = Marshal.GetDelegateForFunctionPointer(fp, typeof(T)); + } + return (T)d; } } } From 1325f5929bd84ca5da482cceeabdead351d39157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Bourbonnais?= Date: Fri, 18 Dec 2020 10:44:39 -0500 Subject: [PATCH 2/2] Use the generic method --- src/runtime/nativecall.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/nativecall.cs b/src/runtime/nativecall.cs index 8bd5a15f2..60259dcd0 100644 --- a/src/runtime/nativecall.cs +++ b/src/runtime/nativecall.cs @@ -45,8 +45,8 @@ internal static T GetDelegate(IntPtr fp) where T: Delegate Delegate d = null; if (!Interop.allocatedThunks.TryGetValue(fp, out d)) { - // Use Marshal.GetDelegateForFunctionPointer<> directly after upgrade the framework - d = Marshal.GetDelegateForFunctionPointer(fp, typeof(T)); + // We don't cache this delegate because this is a pure delegate ot unmanaged. + d = Marshal.GetDelegateForFunctionPointer(fp); } return (T)d; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy