From c0630ca42c5c16a5915cd7a940fa5b5b1cdeebc5 Mon Sep 17 00:00:00 2001 From: Dominique Schuppli Date: Sat, 30 Jan 2021 19:02:01 +0100 Subject: [PATCH 1/3] DynamicProxy puts delegate types in wrong module Back in 95383909 an issue was fixed where DynamicProxy would not always put a generated invocation type in the same dynamic module as the proxy type relying on it. It appears the same issue still exists for generated delegate types. (Those are generated for class proxies when proceeding from intercepted protected methods to the target.) --- .../ClassProxyWithTargetTestCase.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs diff --git a/src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs b/src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs new file mode 100644 index 0000000000..2d4f8d3fb8 --- /dev/null +++ b/src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs @@ -0,0 +1,42 @@ +// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tests +{ + using NUnit.Framework; + + [TestFixture] + public class ClassProxyWithTargetTestCase : BasePEVerifyTestCase + { + [Test] + public void Forwards_to_protected_method() + { + var proxy = generator.CreateClassProxyWithTarget(new ClassWithProtectedMethod()); + Assert.AreEqual(42, proxy.InvokeFortyTwo()); + } + + public class ClassWithProtectedMethod + { + public int InvokeFortyTwo() + { + return FortyTwo(); + } + + protected virtual int FortyTwo() + { + return 42; + } + } + } +} From b72744d864dff0a5873bbc2f65acb52847b853d6 Mon Sep 17 00:00:00 2001 From: Dominique Schuppli Date: Sat, 30 Jan 2021 19:15:44 +0100 Subject: [PATCH 2/3] Emit delegate types in same module as proxy type Thanks to 95383909 the necessary infrastructure is already in place, and we can apply exactly the same fix for delegate types. --- .../DynamicProxy/Generators/DelegateTypeGenerator.cs | 3 ++- .../DynamicProxy/Generators/Emitters/ClassEmitter.cs | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs index 11db73f2ac..8efd6d40cf 100644 --- a/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs @@ -78,7 +78,8 @@ private AbstractTypeEmitter GetEmitter(ClassEmitter @class, INamingScope namingS uniqueName, typeof(MulticastDelegate), Type.EmptyTypes, - DelegateFlags); + DelegateFlags, + forceUnsigned: @class.InStrongNamedModule == false); @delegate.CopyGenericParametersFromMethod(method.Method); return @delegate; } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs index 4a428c8880..cb2023bc87 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs @@ -34,12 +34,6 @@ public ClassEmitter(ModuleScope modulescope, string name, Type baseType, IEnumer { } - public ClassEmitter(ModuleScope modulescope, string name, Type baseType, IEnumerable interfaces, - TypeAttributes flags) - : this(modulescope, name, baseType, interfaces, flags, forceUnsigned: false) - { - } - public ClassEmitter(ModuleScope modulescope, string name, Type baseType, IEnumerable interfaces, TypeAttributes flags, bool forceUnsigned) From 7fb29cc10b12a6768c7fb85d3778e554d068ac94 Mon Sep 17 00:00:00 2001 From: Dominique Schuppli Date: Sat, 30 Jan 2021 19:31:55 +0100 Subject: [PATCH 3/3] Update the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f32091ed3..a34e7bd401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Bugfixes: - Proxying certain `[Serializable]` classes produces proxy types that fail PEVerify test (@stakx, #367) - `private protected` methods are not intercepted (@CrispyDrone, #535) - `System.UIntPtr` unsupported (@stakx, #546) +- DynamicProxy generates two modules when proceeding from a class proxy's protected method to the target, causing an `InvalidOperationException` when saving the generated assembly to disk (@stakx, #569) Deprecations: - Removed support for the .NET Framework < 4.5 and .NET Standard 1.x. (@stakx, #495, #496)