From bdc20538c98dc4b9332daad6e55304488b12563b Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 23 Aug 2022 13:36:02 -0400 Subject: [PATCH] [Java.Interop] RegisterNatives() shouldn't exceed numMethods Context: https://github.com/xamarin/xamarin-android/pull/7285#discussion_r951760448 `Java.Inteorp.JniEnvironment.Types.RegisterNatives()` is overloaded: namespace Java.Interop { partial class JniEnvironment { partial class Types { public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegistration[] methods); public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegistration[] methods, int numMethods); } } } If the `int numMethods` overload is used, then: 1. it should be possible to pass an array which contains *more* than `numMethods` elements, and 2. Passing such an array shouldn't throw an exception. For example: var methods = new JniNativeMethodRegistration [10]; JniEnvironment.Types.RegisterNatives (type, methods, 0); Instead, when using a Debug configuration build of `Java.Interop.dll`, a `NullReferenceException` would be thrown, because the `foreach` loop would traverse *every element*, not just the first `numMethods` elements, which could result in accessing `methods[i].Marshaler.GetType()`, which could be `null`. Fix the `DEBUG && NETCOREAPP` check so that only the first `numMethods` elements are accessed, *not* all of them, and add a `null` check around `JniNativeMethodRegistration.Marshaler` access. This prevents the `NullReferenceException`. --- src/Java.Interop/Java.Interop/JniEnvironment.Types.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs index af0ca4ff1..1ff1c6627 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs @@ -201,8 +201,9 @@ public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegi public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegistration [] methods, int numMethods) { #if DEBUG && NETCOREAPP - foreach (var m in methods) { - if (m.Marshaler.GetType ().GenericTypeArguments.Length != 0) { + for (int i = 0; i < numMethods; ++i) { + var m = methods [i]; + if (m.Marshaler != null && m.Marshaler.GetType ().GenericTypeArguments.Length != 0) { var method = m.Marshaler.Method; Debug.WriteLine ($"JNIEnv::RegisterNatives() given a generic delegate type `{m.Marshaler.GetType()}`. .NET Core doesn't like this."); Debug.WriteLine ($" Java: {m.Name}{m.Signature}");