mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Fix JNI argv parsing: throw exception on NULL
Add new 'jni' test case to ensure this works
This commit is contained in:
parent
e856cafc97
commit
788b3e37b2
@ -117,7 +117,8 @@ static int outv_end_field()
|
||||
return put_blob((jbyte *)outv_buffer, length);
|
||||
}
|
||||
|
||||
int Throw(JNIEnv *env, const char *class, const char *msg){
|
||||
int Throw(JNIEnv *env, const char *class, const char *msg)
|
||||
{
|
||||
jclass exceptionClass = NULL;
|
||||
if ((exceptionClass = (*env)->FindClass(env, class)) == NULL)
|
||||
return -1; // exception
|
||||
@ -157,40 +158,36 @@ JNIEXPORT jint JNICALL Java_org_servalproject_servald_ServalD_rawCommand(JNIEnv
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method totalRowCount");
|
||||
}
|
||||
unsigned char status = 0; // to match what the shell gets: 0..255
|
||||
|
||||
if (jni_env)
|
||||
return Throw(env, "java/lang/IllegalStateException", "re-entrancy not supported");
|
||||
|
||||
// Construct argv, argc from this method's arguments.
|
||||
jsize len = (*env)->GetArrayLength(env, args);
|
||||
const char **argv = alloca(sizeof(char*) * (len + 1));
|
||||
if (argv == NULL)
|
||||
return Throw(env, "java/lang/OutOfMemoryError", "alloca returned NULL");
|
||||
|
||||
argv[len]=NULL;
|
||||
|
||||
return Throw(env, "java/lang/OutOfMemoryError", "alloca() returned NULL");
|
||||
jsize i;
|
||||
for (i = 0; i <= len; ++i)
|
||||
argv[i] = NULL;
|
||||
int argc = len;
|
||||
// From now on, in case of an exception we have to free some resources before
|
||||
// returning.
|
||||
jni_exception = 0;
|
||||
const char *empty="";
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (i = 0; !jni_exception && i < len; ++i) {
|
||||
const jstring arg = (jstring)(*env)->GetObjectArrayElement(env, args, i);
|
||||
if ((*env)->ExceptionOccurred(env))
|
||||
jni_exception = 1;
|
||||
|
||||
argv[i] = empty;
|
||||
if (arg != NULL && !jni_exception){
|
||||
else if (arg == NULL) {
|
||||
Throw(env, "java/lang/NullPointerException", "null element in argv");
|
||||
jni_exception = 1;
|
||||
}
|
||||
else {
|
||||
const char *str = (*env)->GetStringUTFChars(env, arg, NULL);
|
||||
if (str == NULL){
|
||||
if (str == NULL)
|
||||
jni_exception = 1;
|
||||
}else
|
||||
else
|
||||
argv[i] = str;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jni_exception) {
|
||||
// Set up the output buffer.
|
||||
jniResults = outv;
|
||||
@ -200,10 +197,9 @@ JNIEXPORT jint JNICALL Java_org_servalproject_servald_ServalD_rawCommand(JNIEnv
|
||||
status = parseCommandLine(NULL, argc, argv);
|
||||
jni_env = NULL;
|
||||
}
|
||||
|
||||
// Release argv Java string buffers.
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (argv[i] && argv[i]!=empty) {
|
||||
if (argv[i]) {
|
||||
const jstring arg = (jstring)(*env)->GetObjectArrayElement(env, args, i);
|
||||
(*env)->ReleaseStringUTFChars(env, arg, argv[i]);
|
||||
}
|
||||
|
@ -34,5 +34,23 @@ class ServalDTests
|
||||
}
|
||||
System.out.println("");
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void nullArg(String[] args)
|
||||
{
|
||||
ServalD servald = new ServalD();
|
||||
for (int i = 0; i != args.length; ++i)
|
||||
if ("(null)".equals(args[i]))
|
||||
args[i] = null;
|
||||
servald.command(Arrays.copyOfRange(args, 0, args.length));
|
||||
System.out.print(servald.status);
|
||||
for (byte[] a: servald.outv) {
|
||||
System.out.print(":");
|
||||
System.out.print(new String(a));
|
||||
}
|
||||
System.out.println("");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
13
tests/jni
13
tests/jni
@ -47,7 +47,7 @@ assert_echo_works() {
|
||||
|
||||
doc_Echo="Serval JNI echo Hello world"
|
||||
test_Echo() {
|
||||
executeOk java "-Djava.library.path=$LD_LIBRARY_PATH" -classpath "$PWD/classes" org.servalproject.servald.ServalD echo -e 'Hello,\ttab' 'world\0!'
|
||||
executeOk java "-Djava.library.path=$LD_LIBRARY_PATH" -classpath "$PWD/classes" org.servalproject.servald.ServalD 'echo' '-e' 'Hello,\ttab' 'world\0!'
|
||||
assertStdoutIs -e 'Hello,\ttab\nworld\0!\n'
|
||||
}
|
||||
|
||||
@ -64,9 +64,18 @@ test_Delim() {
|
||||
|
||||
doc_Repeat="Serval JNI repeated calls in same process"
|
||||
test_Repeat() {
|
||||
executeOk java "-Djava.library.path=$LD_LIBRARY_PATH" -classpath "$PWD/classes" org.servalproject.servald.ServalDTests repeat 50 echo 'Hello,' 'world!'
|
||||
executeOk --core-backtrace java "-Djava.library.path=$LD_LIBRARY_PATH" -classpath "$PWD/classes" org.servalproject.servald.ServalDTests repeat 50 'echo' 'Hello,' 'world!'
|
||||
assertStdoutLineCount '==' 50
|
||||
assertStdoutGrep --matches=50 '^0:Hello,:world!$'
|
||||
}
|
||||
|
||||
doc_NullArg="Serval JNI null arguments throw exception"
|
||||
test_NullArg() {
|
||||
execute --core-backtrace java "-Djava.library.path=$LD_LIBRARY_PATH" -classpath "$PWD/classes" org.servalproject.servald.ServalDTests nullArg 'echo' '(null)'
|
||||
tfw_cat --stdout --stderr
|
||||
assertExitStatus '!=' 0
|
||||
assertStderrGrep 'NullPointerException: null element in argv'
|
||||
}
|
||||
|
||||
|
||||
runTests "$@"
|
||||
|
Loading…
Reference in New Issue
Block a user