Skip to content

Commit

Permalink
fix: handle remaining JNI calls error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Jan 26, 2021
1 parent af8dff7 commit b5b16d3
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 81 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Check internal JNI calls for pending exceptions and no-op
[#1088](https://github.com/bugsnag/bugsnag-android/pull/1088)
[#1091](https://github.com/bugsnag/bugsnag-android/pull/1091)
[#1092](https://github.com/bugsnag/bugsnag-android/pull/1092)

## 5.5.1 (2021-01-21)

Expand Down
78 changes: 52 additions & 26 deletions bugsnag-plugin-android-ndk/src/main/jni/bugsnag.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ jfieldID bsg_parse_jseverity(JNIEnv *env, bugsnag_severity severity,
jclass severity_class) {
const char *severity_sig = "Lcom/bugsnag/android/Severity;";
if (severity == BSG_SEVERITY_ERR) {
return (*env)->GetStaticFieldID(env, severity_class, "ERROR", severity_sig);
return bsg_safe_get_static_field_id(env, severity_class, "ERROR",
severity_sig);
} else if (severity == BSG_SEVERITY_WARN) {
return (*env)->GetStaticFieldID(env, severity_class, "WARNING",
severity_sig);
return bsg_safe_get_static_field_id(env, severity_class, "WARNING",
severity_sig);
} else {
return (*env)->GetStaticFieldID(env, severity_class, "INFO", severity_sig);
return bsg_safe_get_static_field_id(env, severity_class, "INFO",
severity_sig);
}
}

Expand Down Expand Up @@ -137,28 +139,41 @@ void bugsnag_notify_env(JNIEnv *env, char *name, char *message,
} else {
method = bsg_safe_new_string_utf(env, frame.method);
}

// create StackTraceElement object
jobject jframe =
(*env)->NewObject(env, trace_class, trace_constructor, class, method,
filename, frame.line_number);
bsg_safe_new_object(env, trace_class, trace_constructor, class, method,
filename, frame.line_number);
if (jframe == NULL) {
return;
}

bsg_safe_set_object_array_element(env, trace, i, jframe);
(*env)->DeleteLocalRef(env, filename);
(*env)->DeleteLocalRef(env, class);
(*env)->DeleteLocalRef(env, method);
}

// Create a severity Error
jobject jseverity = (*env)->GetStaticObjectField(
env, severity_class, bsg_parse_jseverity(env, severity, severity_class));
// get the severity field
jfieldID severity_field = bsg_parse_jseverity(env, severity, severity_class);
if (severity_field == NULL) {
return;
}
// get the error severity object
jobject jseverity =
bsg_safe_get_static_object_field(env, severity_class, severity_field);
if (jseverity == NULL) {
return;
}

jbyteArray jname = bsg_byte_ary_from_string(env, name);
jbyteArray jmessage = bsg_byte_ary_from_string(env, message);

// set application's binary arch
bugsnag_set_binary_arch(env);

(*env)->CallStaticVoidMethod(env, interface_class, notify_method, jname,
jmessage, jseverity, trace);
bsg_safe_call_static_void_method(env, interface_class, notify_method, jname,
jmessage, jseverity, trace);

bsg_release_byte_ary(env, jname, name);
bsg_release_byte_ary(env, jmessage, message);
Expand Down Expand Up @@ -190,7 +205,8 @@ void bugsnag_set_binary_arch(JNIEnv *env) {
// call NativeInterface.setBinaryArch()
jstring arch = bsg_safe_new_string_utf(env, bsg_binary_arch());
if (arch != NULL) {
(*env)->CallStaticVoidMethod(env, interface_class, set_arch_method, arch);
bsg_safe_call_static_void_method(env, interface_class, set_arch_method,
arch);
}
(*env)->DeleteLocalRef(env, arch);
(*env)->DeleteLocalRef(env, interface_class);
Expand All @@ -215,8 +231,8 @@ void bugsnag_set_user_env(JNIEnv *env, char *id, char *email, char *name) {
jbyteArray jemail = bsg_byte_ary_from_string(env, email);
jbyteArray jname = bsg_byte_ary_from_string(env, name);

(*env)->CallStaticVoidMethod(env, interface_class, set_user_method, jid,
jemail, jname);
bsg_safe_call_static_void_method(env, interface_class, set_user_method, jid,
jemail, jname);

bsg_release_byte_ary(env, jid, id);
bsg_release_byte_ary(env, jemail, email);
Expand All @@ -232,21 +248,22 @@ jfieldID bsg_parse_jcrumb_type(JNIEnv *env, bugsnag_breadcrumb_type type,
jclass type_class) {
const char *type_sig = "Lcom/bugsnag/android/BreadcrumbType;";
if (type == BSG_CRUMB_USER) {
return (*env)->GetStaticFieldID(env, type_class, "USER", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "USER", type_sig);
} else if (type == BSG_CRUMB_ERROR) {
return (*env)->GetStaticFieldID(env, type_class, "ERROR", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "ERROR", type_sig);
} else if (type == BSG_CRUMB_LOG) {
return (*env)->GetStaticFieldID(env, type_class, "LOG", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "LOG", type_sig);
} else if (type == BSG_CRUMB_NAVIGATION) {
return (*env)->GetStaticFieldID(env, type_class, "NAVIGATION", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "NAVIGATION",
type_sig);
} else if (type == BSG_CRUMB_PROCESS) {
return (*env)->GetStaticFieldID(env, type_class, "PROCESS", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "PROCESS", type_sig);
} else if (type == BSG_CRUMB_REQUEST) {
return (*env)->GetStaticFieldID(env, type_class, "REQUEST", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "REQUEST", type_sig);
} else if (type == BSG_CRUMB_STATE) {
return (*env)->GetStaticFieldID(env, type_class, "STATE", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "STATE", type_sig);
} else { // MANUAL is the default type
return (*env)->GetStaticFieldID(env, type_class, "MANUAL", type_sig);
return bsg_safe_get_static_field_id(env, type_class, "MANUAL", type_sig);
}
}

Expand Down Expand Up @@ -274,11 +291,20 @@ void bugsnag_leave_breadcrumb_env(JNIEnv *env, char *message,
return;
}

jobject jtype = (*env)->GetStaticObjectField(
env, type_class, bsg_parse_jcrumb_type(env, type, type_class));
// get breadcrumb type fieldID
jfieldID crumb_type = bsg_parse_jcrumb_type(env, type, type_class);
if (crumb_type == NULL) {
return;
}

// get the breadcrumb type
jobject jtype = bsg_safe_get_static_object_field(env, type_class, crumb_type);
if (jtype == NULL) {
return;
}
jbyteArray jmessage = bsg_byte_ary_from_string(env, message);
(*env)->CallStaticVoidMethod(env, interface_class, leave_breadcrumb_method,
jmessage, jtype);
bsg_safe_call_static_void_method(env, interface_class,
leave_breadcrumb_method, jmessage, jtype);
bsg_release_byte_ary(env, jmessage, message);
(*env)->DeleteLocalRef(env, jtype);
(*env)->DeleteLocalRef(env, jmessage);
Expand Down
4 changes: 2 additions & 2 deletions bugsnag-plugin-android-ndk/src/main/jni/bugsnag_ndk.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ Java_com_bugsnag_android_ndk_NativeBridge_deliverReportAtPath(
// call NativeInterface.deliverReport()
jstring japi_key = bsg_safe_new_string_utf(env, event->api_key);
if (japi_key != NULL) {
(*env)->CallStaticVoidMethod(env, interface_class, jdeliver_method,
jstage, jpayload, japi_key);
bsg_safe_call_static_void_method(env, interface_class, jdeliver_method,
jstage, jpayload, japi_key);
}
(*env)->DeleteLocalRef(env, japi_key);

Expand Down
89 changes: 61 additions & 28 deletions bugsnag-plugin-android-ndk/src/main/jni/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ jobject bsg_get_map_value_obj(JNIEnv *env, bsg_jni_cache *jni_cache,
return NULL;
}

jobject obj =
(*env)->CallObjectMethod(env, map, jni_cache->hash_map_get, key);
jobject obj = bsg_safe_call_static_object_method(
env, map, jni_cache->hash_map_get, key);
(*env)->DeleteLocalRef(env, key);
return obj;
}
Expand Down Expand Up @@ -320,8 +320,8 @@ int bsg_populate_cpu_abi_from_map(JNIEnv *env, bsg_jni_cache *jni_cache,
return 0;
}

jobjectArray _value =
(*env)->CallObjectMethod(env, map, jni_cache->hash_map_get, key);
jobjectArray _value = bsg_safe_call_static_object_method(
env, map, jni_cache->hash_map_get, key);
if (_value != NULL) {
int count = (*env)->GetArrayLength(env, _value);

Expand Down Expand Up @@ -360,16 +360,23 @@ void bsg_populate_crumb_metadata(JNIEnv *env, bugsnag_breadcrumb *crumb,
return;
}

// create a list of metadata keys
jobject keyset =
(*env)->CallObjectMethod(env, metadata, jni_cache->map_key_set);
jobject keylist = (*env)->NewObject(
bsg_safe_call_static_object_method(env, metadata, jni_cache->map_key_set);
if (keyset == NULL) {
return;
}
jobject keylist = bsg_safe_new_object(
env, jni_cache->arraylist, jni_cache->arraylist_init_with_obj, keyset);
if (keylist == NULL) {
return;
}

for (int i = 0; i < map_size; i++) {
jstring _key = (*env)->CallObjectMethod(env, keylist,
jni_cache->arraylist_get, (jint)i);
jobject _value =
(*env)->CallObjectMethod(env, metadata, jni_cache->map_get, _key);
jstring _key = bsg_safe_call_static_object_method(
env, keylist, jni_cache->arraylist_get, (jint)i);
jobject _value = bsg_safe_call_static_object_method(
env, metadata, jni_cache->map_get, _key);

if (_key == NULL || _value == NULL) {
(*env)->DeleteLocalRef(env, _key);
Expand Down Expand Up @@ -402,8 +409,11 @@ char *bsg_binary_arch() {

void bsg_populate_app_data(JNIEnv *env, bsg_jni_cache *jni_cache,
bugsnag_event *event) {
jobject data = (*env)->CallStaticObjectMethod(
jobject data = bsg_safe_call_static_object_method(
env, jni_cache->native_interface, jni_cache->get_app_data);
if (data == NULL) {
return;
}

bsg_strncpy_safe(event->app.binary_arch, bsg_binary_arch(),
sizeof(event->app.binary_arch));
Expand Down Expand Up @@ -479,8 +489,11 @@ void populate_device_metadata(JNIEnv *env, bsg_jni_cache *jni_cache,

void bsg_populate_device_data(JNIEnv *env, bsg_jni_cache *jni_cache,
bugsnag_event *event) {
jobject data = (*env)->CallStaticObjectMethod(
jobject data = bsg_safe_call_static_object_method(
env, jni_cache->native_interface, jni_cache->get_device_data);
if (data == NULL) {
return;
}

bsg_populate_cpu_abi_from_map(env, jni_cache, data, &event->device);

Expand Down Expand Up @@ -528,8 +541,11 @@ void bsg_populate_device_data(JNIEnv *env, bsg_jni_cache *jni_cache,

void bsg_populate_user_data(JNIEnv *env, bsg_jni_cache *jni_cache,
bugsnag_event *event) {
jobject data = (*env)->CallStaticObjectMethod(
jobject data = bsg_safe_call_static_object_method(
env, jni_cache->native_interface, jni_cache->get_user_data);
if (data == NULL) {
return;
}
bsg_copy_map_value_string(env, jni_cache, data, "id", event->user.id,
sizeof(event->user.id));
bsg_copy_map_value_string(env, jni_cache, data, "name", event->user.name,
Expand All @@ -541,7 +557,7 @@ void bsg_populate_user_data(JNIEnv *env, bsg_jni_cache *jni_cache,

void bsg_populate_context(JNIEnv *env, bsg_jni_cache *jni_cache,
bugsnag_event *event) {
jstring _context = (*env)->CallStaticObjectMethod(
jstring _context = bsg_safe_call_static_object_method(
env, jni_cache->native_interface, jni_cache->get_context);
if (_context != NULL) {
const char *value = (*env)->GetStringUTFChars(env, (jstring)_context, 0);
Expand Down Expand Up @@ -591,40 +607,57 @@ void bsg_populate_metadata(JNIEnv *env, bugsnag_metadata *dst,
return;
}
if (metadata == NULL) {
metadata = (*env)->CallStaticObjectMethod(env, jni_cache->native_interface,
jni_cache->get_metadata);
metadata = bsg_safe_call_static_object_method(
env, jni_cache->native_interface, jni_cache->get_metadata);
}
if (metadata != NULL) {
int size = bsg_safe_call_int_method(env, metadata, jni_cache->map_size);
if (size == -1) {
return;
}
jobject keyset =
(*env)->CallObjectMethod(env, metadata, jni_cache->map_key_set);
jobject keylist = (*env)->NewObject(

// create a list of metadata keys
jobject keyset = bsg_safe_call_static_object_method(env, metadata,
jni_cache->map_key_set);
if (keyset == NULL) {
return;
}
jobject keylist = bsg_safe_new_object(
env, jni_cache->arraylist, jni_cache->arraylist_init_with_obj, keyset);
if (keylist == NULL) {
return;
}

for (int i = 0; i < size; i++) {
jstring _key = (*env)->CallObjectMethod(
jstring _key = bsg_safe_call_static_object_method(
env, keylist, jni_cache->arraylist_get, (jint)i);
if (_key == NULL) {
return;
}
char *section = (char *)(*env)->GetStringUTFChars(env, _key, 0);
jobject _section =
(*env)->CallObjectMethod(env, metadata, jni_cache->map_get, _key);
bsg_safe_call_object_method(env, metadata, jni_cache->map_get, _key);
jint section_size =
bsg_safe_call_int_method(env, _section, jni_cache->map_size);
if (section_size == -1) {
break;
}
jobject section_keyset =
(*env)->CallObjectMethod(env, _section, jni_cache->map_key_set);
jobject section_keylist =
(*env)->NewObject(env, jni_cache->arraylist,
jni_cache->arraylist_init_with_obj, section_keyset);
jobject section_keyset = bsg_safe_call_static_object_method(
env, _section, jni_cache->map_key_set);
jobject section_keylist = bsg_safe_new_object(
env, jni_cache->arraylist, jni_cache->arraylist_init_with_obj,
section_keyset);
if (keylist == NULL || keyset) {
break;
}
for (int j = 0; j < section_size; j++) {
jstring section_key = (*env)->CallObjectMethod(
jstring section_key = bsg_safe_call_static_object_method(
env, section_keylist, jni_cache->arraylist_get, (jint)j);
if (section_key == NULL) {
break;
}
char *name = (char *)(*env)->GetStringUTFChars(env, section_key, 0);
jobject _value = (*env)->CallObjectMethod(
jobject _value = bsg_safe_call_static_object_method(
env, section, jni_cache->map_get, section_key);
bsg_populate_metadata_value(env, dst, jni_cache, section, name, _value);
(*env)->ReleaseStringUTFChars(env, section_key, name);
Expand Down
Loading

0 comments on commit b5b16d3

Please sign in to comment.