Fix crash Java directors
Further crash fixes when using OUTPUT and INOUT typemaps in typemaps.i and
passing NULL pointers in C++ to director method overloaded and implemented
in Java.
Don't create the one element array in these directorin typemaps if the
input is a NULL pointer, that is, translate a NULL C++ pointer into a
null Java object.
Also add some missing JNI error checks in these typemaps.
diff --git a/CHANGES.current b/CHANGES.current
index 1f25e91..85d1ffe 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@
Version 4.0.0 (in progress)
===========================
+2018-08-12: brianhatwood,wsfulton
+ [Java] #1303 #1304 Fix crash in directors when using OUTPUT and INOUT typemaps in typemaps.i and
+ passing NULL pointers in C++ to director method overloaded and implemented in Java.
+
2018-08-10: wsfulton
[Python] #1293 Improve TypeError message inconsistencies between default and fastdispatch
mode when handling overloaded C++ functions. Previously the error message did not always
diff --git a/Examples/test-suite/java/java_director_typemaps_ptr_runme.java b/Examples/test-suite/java/java_director_typemaps_ptr_runme.java
index fdd0bfd..c387270 100644
--- a/Examples/test-suite/java/java_director_typemaps_ptr_runme.java
+++ b/Examples/test-suite/java/java_director_typemaps_ptr_runme.java
@@ -16,8 +16,11 @@
public static void main(String argv[]) {
- Quux quux = new java_director_typemaps_ptr_MyQuux();
+ java_director_typemaps_ptr_MyQuux myquux = new java_director_typemaps_ptr_MyQuux();
+ Quux quux = myquux;
quux.etest();
+ myquux.testing_nulls = true;
+ quux.nulltest();
}
}
@@ -25,6 +28,7 @@
public java_director_typemaps_ptr_MyQuux() {
super();
}
+ public boolean testing_nulls = false;
public void director_method_output(
boolean[] bool_arg,
@@ -47,19 +51,34 @@
float[] float_arg,
double[] double_arg)
{
- bool_arg[0] = true;
- signed_char_arg[0] = 1;
- unsigned_char_arg[0] = 2;
- short_arg[0] = 3;
- unsigned_short_arg[0] = 4;
- int_arg[0] = 5;
- unsigned_int_arg[0] = 6;
- long_arg[0] = 7;
- unsigned_long_arg[0] = 8;
- long_long_arg[0] = 9;
- // unsigned_long_long_arg[0] = 10;
- float_arg[0] = 11;
- double_arg[0] = 12;
+ if (testing_nulls) {
+ if (bool_arg != null) throw new RuntimeException("not null bool_arg");
+ if (signed_char_arg != null) throw new RuntimeException("not null signed_char_arg");
+ if (unsigned_char_arg != null) throw new RuntimeException("not null unsigned_char_arg");
+ if (short_arg != null) throw new RuntimeException("not null short_arg");
+ if (unsigned_short_arg != null) throw new RuntimeException("not null unsigned_short_arg");
+ if (int_arg != null) throw new RuntimeException("not null int_arg");
+ if (unsigned_int_arg != null) throw new RuntimeException("not null unsigned_int_arg");
+ if (long_arg != null) throw new RuntimeException("not null long_arg");
+ if (unsigned_long_arg != null) throw new RuntimeException("not null unsigned_long_arg");
+ if (long_long_arg != null) throw new RuntimeException("not null long_long_arg");
+ // if (unsigned_long_long_arg != null) throw new RuntimeException("not null unsigned_long_long_arg");
+ if (float_arg != null) throw new RuntimeException("not null float_arg");
+ if (double_arg != null) throw new RuntimeException("not null double_arg");
+ }
+ if (bool_arg != null) bool_arg[0] = true;
+ if (signed_char_arg != null) signed_char_arg[0] = 1;
+ if (unsigned_char_arg != null) unsigned_char_arg[0] = 2;
+ if (short_arg != null) short_arg[0] = 3;
+ if (unsigned_short_arg != null) unsigned_short_arg[0] = 4;
+ if (int_arg != null) int_arg[0] = 5;
+ if (unsigned_int_arg != null) unsigned_int_arg[0] = 6;
+ if (long_arg != null) long_arg[0] = 7;
+ if (unsigned_long_arg != null) unsigned_long_arg[0] = 8;
+ if (long_long_arg != null) long_long_arg[0] = 9;
+ // if (unsigned_long_long_arg != null) unsigned_long_long_arg[0] = 10;
+ if (float_arg != null) float_arg[0] = 11;
+ if (double_arg != null) double_arg[0] = 12;
}
public void director_method_inout(
@@ -83,34 +102,49 @@
float[] float_arg,
double[] double_arg)
{
- if (bool_arg[0]) throw new RuntimeException("unexpected value for bool_arg");
+ if (testing_nulls) {
+ if (bool_arg != null) throw new RuntimeException("not null bool_arg");
+ if (signed_char_arg != null) throw new RuntimeException("not null signed_char_arg");
+ if (unsigned_char_arg != null) throw new RuntimeException("not null unsigned_char_arg");
+ if (short_arg != null) throw new RuntimeException("not null short_arg");
+ if (unsigned_short_arg != null) throw new RuntimeException("not null unsigned_short_arg");
+ if (int_arg != null) throw new RuntimeException("not null int_arg");
+ if (unsigned_int_arg != null) throw new RuntimeException("not null unsigned_int_arg");
+ if (long_arg != null) throw new RuntimeException("not null long_arg");
+ if (unsigned_long_arg != null) throw new RuntimeException("not null unsigned_long_arg");
+ if (long_long_arg != null) throw new RuntimeException("not null long_long_arg");
+ // if (unsigned_long_long_arg != null) throw new RuntimeException("not null unsigned_long_long_arg");
+ if (float_arg != null) throw new RuntimeException("not null float_arg");
+ if (double_arg != null) throw new RuntimeException("not null double_arg");
+ } else {
+ if (bool_arg[0]) throw new RuntimeException("unexpected value for bool_arg");
+ if (signed_char_arg[0] != 101) throw new RuntimeException("unexpected value for signed_char_arg");
+ if (unsigned_char_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_char_arg");
+ if (short_arg[0] != 101) throw new RuntimeException("unexpected value for short_arg");
+ if (unsigned_short_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_short_arg");
+ if (int_arg[0] != 101) throw new RuntimeException("unexpected value for int_arg");
+ if (unsigned_int_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_int_arg");
+ if (long_arg[0] != 101) throw new RuntimeException("unexpected value for long_arg");
+ if (unsigned_long_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_long_arg");
+ if (long_long_arg[0] != 101) throw new RuntimeException("unexpected value for long_long_arg");
+ // if (unsigned_long_long_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_long_long_arg");
+ if (float_arg[0] != 101) throw new RuntimeException("unexpected value for float_arg");
+ if (double_arg[0] != 101) throw new RuntimeException("unexpected value for double_arg");
+ }
- if (signed_char_arg[0] != 101) throw new RuntimeException("unexpected value for signed_char_arg");
- if (unsigned_char_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_char_arg");
- if (short_arg[0] != 101) throw new RuntimeException("unexpected value for short_arg");
- if (unsigned_short_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_short_arg");
- if (int_arg[0] != 101) throw new RuntimeException("unexpected value for int_arg");
- if (unsigned_int_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_int_arg");
- if (long_arg[0] != 101) throw new RuntimeException("unexpected value for long_arg");
- if (unsigned_long_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_long_arg");
- if (long_long_arg[0] != 101) throw new RuntimeException("unexpected value for long_long_arg");
- // if (unsigned_long_long_arg[0] != 101) throw new RuntimeException("unexpected value for unsigned_long_long_arg");
- if (float_arg[0] != 101) throw new RuntimeException("unexpected value for float_arg");
- if (double_arg[0] != 101) throw new RuntimeException("unexpected value for double_arg");
-
- bool_arg[0] = false;
- signed_char_arg[0] = 11;
- unsigned_char_arg[0] = 12;
- short_arg[0] = 13;
- unsigned_short_arg[0] = 14;
- int_arg[0] = 15;
- unsigned_int_arg[0] = 16;
- long_arg[0] = 17;
- unsigned_long_arg[0] = 18;
- long_long_arg[0] = 19;
- // unsigned_long_long_arg[0] = 110;
- float_arg[0] = 111;
- double_arg[0] = 112;
+ if (bool_arg != null) bool_arg[0] = false;
+ if (signed_char_arg != null) signed_char_arg[0] = 11;
+ if (unsigned_char_arg != null) unsigned_char_arg[0] = 12;
+ if (short_arg != null) short_arg[0] = 13;
+ if (unsigned_short_arg != null) unsigned_short_arg[0] = 14;
+ if (int_arg != null) int_arg[0] = 15;
+ if (unsigned_int_arg != null) unsigned_int_arg[0] = 16;
+ if (long_arg != null) long_arg[0] = 17;
+ if (unsigned_long_arg != null) unsigned_long_arg[0] = 18;
+ if (long_long_arg != null) long_long_arg[0] = 19;
+ // if (unsigned_long_long_arg != null) unsigned_long_long_arg[0] = 110;
+ if (float_arg != null) float_arg[0] = 111;
+ if (double_arg != null) double_arg[0] = 112;
}
public void director_method_nameless_args(
@@ -134,18 +168,33 @@
float[] float_arg,
double[] double_arg)
{
- bool_arg[0] = true;
- signed_char_arg[0] = 12;
- unsigned_char_arg[0] = 13;
- short_arg[0] = 14;
- unsigned_short_arg[0] = 15;
- int_arg[0] = 16;
- unsigned_int_arg[0] = 17;
- long_arg[0] = 18;
- unsigned_long_arg[0] = 19;
- long_long_arg[0] = 20;
- // unsigned_long_long_arg[0] = 111;
- float_arg[0] = 112;
- double_arg[0] = 113;
+ if (testing_nulls) {
+ if (bool_arg != null) throw new RuntimeException("not null bool_arg");
+ if (signed_char_arg != null) throw new RuntimeException("not null signed_char_arg");
+ if (unsigned_char_arg != null) throw new RuntimeException("not null unsigned_char_arg");
+ if (short_arg != null) throw new RuntimeException("not null short_arg");
+ if (unsigned_short_arg != null) throw new RuntimeException("not null unsigned_short_arg");
+ if (int_arg != null) throw new RuntimeException("not null int_arg");
+ if (unsigned_int_arg != null) throw new RuntimeException("not null unsigned_int_arg");
+ if (long_arg != null) throw new RuntimeException("not null long_arg");
+ if (unsigned_long_arg != null) throw new RuntimeException("not null unsigned_long_arg");
+ if (long_long_arg != null) throw new RuntimeException("not null long_long_arg");
+ // if (unsigned_long_long_arg != null) throw new RuntimeException("not null unsigned_long_long_arg");
+ if (float_arg != null) throw new RuntimeException("not null float_arg");
+ if (double_arg != null) throw new RuntimeException("not null double_arg");
+ }
+ if (bool_arg != null) bool_arg[0] = true;
+ if (signed_char_arg != null) signed_char_arg[0] = 12;
+ if (unsigned_char_arg != null) unsigned_char_arg[0] = 13;
+ if (short_arg != null) short_arg[0] = 14;
+ if (unsigned_short_arg != null) unsigned_short_arg[0] = 15;
+ if (int_arg != null) int_arg[0] = 16;
+ if (unsigned_int_arg != null) unsigned_int_arg[0] = 17;
+ if (long_arg != null) long_arg[0] = 18;
+ if (unsigned_long_arg != null) unsigned_long_arg[0] = 19;
+ if (long_long_arg != null) long_long_arg[0] = 20;
+ // if (unsigned_long_long_arg != null) unsigned_long_long_arg[0] = 111;
+ if (float_arg != null) float_arg[0] = 112;
+ if (double_arg != null) double_arg[0] = 113;
}
}
diff --git a/Examples/test-suite/java_director_typemaps_ptr.i b/Examples/test-suite/java_director_typemaps_ptr.i
index dcae1d8..578001a 100644
--- a/Examples/test-suite/java_director_typemaps_ptr.i
+++ b/Examples/test-suite/java_director_typemaps_ptr.i
@@ -344,6 +344,71 @@
verify(floatarg_inout == 112);
verify(doublearg_inout == 113);
}
+
+ void nulltest() {
+ director_method_output(
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ // NULL,
+
+ NULL,
+ NULL);
+
+ director_method_inout(
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ // NULL,
+
+ NULL,
+ NULL);
+
+ director_method_nameless_args(
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ // NULL,
+
+ NULL,
+ NULL);
+ }
};
%}
diff --git a/Lib/java/typemaps.i b/Lib/java/typemaps.i
index fd7c267..e130c19 100644
--- a/Lib/java/typemaps.i
+++ b/Lib/java/typemaps.i
@@ -212,8 +212,16 @@
JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &jvalue);
}
-%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT, TYPE *OUTPUT %{
+%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT %{
$input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+ if (!$input) return $null;
+ Swig::LocalRefGuard $1_refguard(jenv, $input); %}
+
+%typemap(directorin,descriptor=JNIDESC) TYPE *OUTPUT %{
+ if ($1) {
+ $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+ if (!$input) return $null;
+ }
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(directorargout, noblock=1) TYPE &OUTPUT
@@ -225,9 +233,11 @@
%typemap(directorargout, noblock=1) TYPE *OUTPUT
{
- JNITYPE $1_jvalue;
- JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- if ($result) *$result = ($*1_ltype)$1_jvalue;
+ if ($result) {
+ JNITYPE $1_jvalue;
+ JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+ *$result = ($*1_ltype)$1_jvalue;
+ }
}
%typemap(typecheck) TYPE *OUTPUT = TYPECHECKTYPE;
@@ -273,9 +283,11 @@
%typemap(directorargout, noblock=1) bool *OUTPUT
{
- jboolean $1_jvalue;
- JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = $1_jvalue ? true : false;
+ if ($result) {
+ jboolean $1_jvalue;
+ JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+ *$result = $1_jvalue ? true : false;
+ }
}
@@ -388,14 +400,18 @@
%typemap(directorin,descriptor=JNIDESC) TYPE &INOUT %{
$input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+ if (!$input) return $null;
JNITYPE $1_jvalue = (JNITYPE)$1;
JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(directorin,descriptor=JNIDESC) TYPE *INOUT %{
- $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
- JNITYPE $1_jvalue = (JNITYPE)*$1;
- JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+ if ($1) {
+ $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+ if (!$input) return $null;
+ JNITYPE $1_jvalue = (JNITYPE)*$1;
+ JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+ }
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(directorargout, noblock=1) TYPE &INOUT
@@ -406,8 +422,11 @@
%typemap(directorargout, noblock=1) TYPE *INOUT
{
- JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = ($*1_ltype)$1_jvalue;
+ if ($result) {
+ JNITYPE $1_jvalue;
+ JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+ *$result = ($*1_ltype)$1_jvalue;
+ }
}
%typemap(typecheck) TYPE *INOUT = TYPECHECKTYPE;
@@ -459,8 +478,11 @@
%typemap(directorargout, noblock=1) bool *INOUT
{
- JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = $1_jvalue ? true : false;
+ if ($result) {
+ jboolean $1_jvalue;
+ JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+ *$result = $1_jvalue ? true : false;
+ }
}