From 1832ee9efb4eab5ce9049658f55d72dcc0791482 Mon Sep 17 00:00:00 2001 From: AndyBevan <7716304+AndyBevan@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:49:31 -0500 Subject: [PATCH 1/5] Added more verbose error message when calling method using reflection and target type does not match passed type (fixes #97022) --- .../System.Private.CoreLib/src/Resources/Strings.resx | 3 +++ .../src/System/Reflection/MethodInvokerCommon.cs | 2 +- .../System.Reflection.Tests/DefaultBinderTests.cs | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index b721414a66962..fe1f8d4a09657 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -3341,6 +3341,9 @@ Object does not match target type. + + Object of type {0} does not match target type {1}. + Non-static field requires a target. diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs index 0096a9f397c39..4eda76d9364b7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs @@ -96,7 +96,7 @@ internal static void ValidateInvokeTarget(object? target, MethodBase method) if (!method.DeclaringType!.IsInstanceOfType(target)) { - throw new TargetException(SR.RFLCT_Targ_ITargMismatch); + throw new TargetException(SR.Format(SR.RFLCT_Targ_ITargMismatch_WithType, method.DeclaringType.Name, target.GetType().Name)); } } diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs index 874e1f3d5864c..66ba248723fdb 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs @@ -107,6 +107,17 @@ public static void DefaultBinderNamedParametersSkippedAndOutOfOrderTest() Assert.Equal("MethodMoreParameters", method.Name); } + [Fact] + public void InvokeWithIncorrectTargetTypeThrowsCorrectException() + { + Type t = typeof(Sample); + object incorrectInstance = Activator.CreateInstance(t); + MethodInvoker invoker = MethodInvoker.Create(typeof(Test).GetMethod(nameof(Test.TestMethod))); + + TargetException ex = Assert.Throws(() => invoker.Invoke(obj: incorrectInstance, "NotAnInt")); + Assert.Equal("Object of type Test does not match target type Sample.", ex.Message); + } + [Fact] public static void InvokeWithNamedParameters1st2ndTest() { From a31a219e5c4145c8dbcda189f818d52af60ef2dc Mon Sep 17 00:00:00 2001 From: AndyBevan <7716304+AndyBevan@users.noreply.github.com> Date: Fri, 9 Feb 2024 09:46:42 -0500 Subject: [PATCH 2/5] Fixed resource string as per PR comment --- .../System.Private.CoreLib/src/Resources/Strings.resx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index fe1f8d4a09657..836984e4f6fa8 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -3342,7 +3342,7 @@ Object does not match target type. - Object of type {0} does not match target type {1}. + Object type {0} does not match target type {1}. Non-static field requires a target. @@ -4304,4 +4304,4 @@ Blocking wait is not supported on the JS interop threads. - \ No newline at end of file + From 2661679a0c511f916f007d8abafe8bbc5703b30a Mon Sep 17 00:00:00 2001 From: AndyBevan <7716304+AndyBevan@users.noreply.github.com> Date: Fri, 9 Feb 2024 11:30:11 -0500 Subject: [PATCH 3/5] Fixed the test related to a resource string change --- .../tests/System.Reflection.Tests/DefaultBinderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs index 66ba248723fdb..9e5263e295b64 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs @@ -115,7 +115,7 @@ public void InvokeWithIncorrectTargetTypeThrowsCorrectException() MethodInvoker invoker = MethodInvoker.Create(typeof(Test).GetMethod(nameof(Test.TestMethod))); TargetException ex = Assert.Throws(() => invoker.Invoke(obj: incorrectInstance, "NotAnInt")); - Assert.Equal("Object of type Test does not match target type Sample.", ex.Message); + Assert.Equal("Object type Test does not match target type Sample.", ex.Message); } [Fact] From 5083f8cb047cb902b467e5e8f4c0999f68568d0a Mon Sep 17 00:00:00 2001 From: AndyBevan <7716304+AndyBevan@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:14:51 -0500 Subject: [PATCH 4/5] Modified test to have a contains check rather than validating the English string. --- .../tests/System.Reflection.Tests/DefaultBinderTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs index 9e5263e295b64..d1c1f63d830e0 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs @@ -115,7 +115,8 @@ public void InvokeWithIncorrectTargetTypeThrowsCorrectException() MethodInvoker invoker = MethodInvoker.Create(typeof(Test).GetMethod(nameof(Test.TestMethod))); TargetException ex = Assert.Throws(() => invoker.Invoke(obj: incorrectInstance, "NotAnInt")); - Assert.Equal("Object type Test does not match target type Sample.", ex.Message); + Assert.Contains(nameof(Test), ex.Message); + Assert.Contains(nameof(Sample), ex.Message); } [Fact] From 1b6fe458311a5222275cdb55d862d3a04a07da98 Mon Sep 17 00:00:00 2001 From: AndyBevan <7716304+AndyBevan@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:23:22 -0500 Subject: [PATCH 5/5] Modifications to AOT implementation for validating target type when a method is invoked using reflection, inline with other PR changes --- .../src/Internal/Reflection/Core/Execution/MethodBaseInvoker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/MethodBaseInvoker.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/MethodBaseInvoker.cs index 78fc4d99d2792..a14c0007dc8f1 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/MethodBaseInvoker.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/MethodBaseInvoker.cs @@ -57,7 +57,7 @@ protected static void ValidateThis(object thisObject, RuntimeTypeHandle declarin throw new TargetException(SR.RFLCT_Targ_StatMethReqTarg); if (!RuntimeAugments.IsAssignable(thisObject, declaringTypeHandle)) - throw new TargetException(SR.RFLCT_Targ_ITargMismatch); + throw new TargetException(SR.Format(SR.RFLCT_Targ_ITargMismatch_WithType, declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle().Name, thisObject.GetType().Name)); } } }