Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
`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`.

Additionally, add some parameter validation and throw an
`ArgumentOutOfRangeException` if `numMethods` is negative or is
greater than `methods.Length`.
  • Loading branch information
jonpryor authored Aug 23, 2022
1 parent d3ea180 commit e31d9c6
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/Java.Interop/Java.Interop/JniEnvironment.Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,15 @@ public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegi

public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegistration [] methods, int numMethods)
{
if ((numMethods < 0) ||
(numMethods > (methods?.Length ?? 0))) {
throw new ArgumentOutOfRangeException (nameof (numMethods), numMethods,
$"`numMethods` must be between 0 and `methods.Length` ({methods?.Length ?? 0})!");
}
#if DEBUG && NETCOREAPP
foreach (var m in methods) {
if (m.Marshaler.GetType ().GenericTypeArguments.Length != 0) {
for (int i = 0; methods != null && 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}");
Expand Down

0 comments on commit e31d9c6

Please sign in to comment.