From e8f1620e347a314fd983e360768601740d01b170 Mon Sep 17 00:00:00 2001 From: stakx Date: Fri, 2 Oct 2020 22:51:43 +0200 Subject: [PATCH 1/3] Add test showing that private protected methods aren't intercepted --- .../DynamicProxy.Tests/AccessLevelTestCase.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/Castle.Core.Tests/DynamicProxy.Tests/AccessLevelTestCase.cs b/src/Castle.Core.Tests/DynamicProxy.Tests/AccessLevelTestCase.cs index f02435eab8..84821497c6 100644 --- a/src/Castle.Core.Tests/DynamicProxy.Tests/AccessLevelTestCase.cs +++ b/src/Castle.Core.Tests/DynamicProxy.Tests/AccessLevelTestCase.cs @@ -14,6 +14,7 @@ namespace Castle.DynamicProxy.Tests { + using System; using System.Collections.Generic; using System.Reflection; @@ -85,5 +86,50 @@ public void InternalConstructorIsReplicatedWhenInternalsVisibleTo() object proxy = generator.CreateClassProxy(typeof(InternalClass), new StandardInterceptor()); Assert.IsNotNull(proxy.GetType().GetConstructor(new[] { typeof(IInterceptor[]) })); } + + [TestCase(typeof(InternalMethodClass))] + [TestCase(typeof(PrivateProtectedMethodClass))] + [TestCase(typeof(ProtectedMethodClass))] + [TestCase(typeof(ProtectedInternalMethodClass))] + public void Methods_made_visible_by_InternalsVisibleTo_can_be_intercepted(Type methodClass) + { + var method = methodClass.GetMethod("Method", BindingFlags.NonPublic | BindingFlags.Instance); + Assume.That(ProxyUtil.IsAccessible(method)); // because this assembly makes its internals visible to DynamicProxy + + var realObj = (IMethodClass)Activator.CreateInstance(methodClass); + Assert.Throws(realObj.InvokeMethod); + + var proxy = (IMethodClass)generator.CreateClassProxy(methodClass, new DoNothingInterceptor()); + Assert.DoesNotThrow(proxy.InvokeMethod); + } + + private interface IMethodClass + { + void InvokeMethod(); + } + + public class InternalMethodClass : IMethodClass + { + public void InvokeMethod() => Method(); + internal virtual void Method() => throw new Exception(); + } + + public class PrivateProtectedMethodClass : IMethodClass + { + public void InvokeMethod() => Method(); + private protected virtual void Method() => throw new Exception(); + } + + public class ProtectedMethodClass : IMethodClass + { + public void InvokeMethod() => Method(); + protected virtual void Method() => throw new Exception(); + } + + public class ProtectedInternalMethodClass : IMethodClass + { + public void InvokeMethod() => Method(); + protected internal virtual void Method() => throw new Exception(); + } } } From 0c9f53e729c7777321b77d20e68a02721efa896b Mon Sep 17 00:00:00 2001 From: stakx Date: Fri, 2 Oct 2020 23:29:42 +0200 Subject: [PATCH 2/3] Account for `FamANDAssem` accessiblity in `MembersCollector` --- src/Castle.Core/DynamicProxy/Contributors/MembersCollector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Castle.Core/DynamicProxy/Contributors/MembersCollector.cs b/src/Castle.Core/DynamicProxy/Contributors/MembersCollector.cs index dbb5e2a036..4e19d59ec4 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/MembersCollector.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/MembersCollector.cs @@ -223,7 +223,7 @@ protected bool AcceptMethod(MethodInfo method, bool onlyVirtuals, IProxyGenerati } //can only proxy methods that are public or protected (or internals that have already been checked above) - if ((method.IsPublic || method.IsFamily || method.IsAssembly || method.IsFamilyOrAssembly) == false) + if ((method.IsPublic || method.IsFamily || method.IsAssembly || method.IsFamilyOrAssembly || method.IsFamilyAndAssembly) == false) { return false; } From b1baa7337719e6b6aaf1461af6a9d1af27dc297b Mon Sep 17 00:00:00 2001 From: stakx Date: Fri, 2 Oct 2020 23:31:13 +0200 Subject: [PATCH 3/3] Update the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ef123bddd..4c9e232510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Enhancements: - .NET Standard 2.0 and 2.1 support (@lg2de, #485) Bugfixes: +- `private protected` methods are not intercepted (@CrispyDrone, #535) - `System.UIntPtr` unsupported (@stakx, #546) Deprecations: