Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix potential segfaults when adding breadcrumb with NDK #546

Merged
merged 8 commits into from
Aug 1, 2019
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## TBD

### Bug fixes
* Fix potential segfaults when adding breadcrumb with NDK
[#546](https://github.com/bugsnag/bugsnag-android/pull/546)

## 4.17.1 (2019-07-24)

### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.bugsnag.android

import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotSame
import org.junit.Assert.assertTrue
import org.junit.Test

class BreadcrumbMutabilityTest {

@Test
fun breadcrumbCopiesMap() {
val data = mutableMapOf<String, String>()
val breadcrumb = Breadcrumb("foo", BreadcrumbType.MANUAL, data)
data["a"] = "bar"
assertTrue(breadcrumb.metadata.isEmpty())
assertNotSame(data, breadcrumb.metadata)
}

@Test
fun breadcrumbProtectsMetaData() {
val data = mutableMapOf<String, String>()
val breadcrumb = Breadcrumb("foo", BreadcrumbType.MANUAL, data)
breadcrumb.metadata["a"] = "bar"
assertFalse(breadcrumb.metadata.isEmpty())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -40,10 +41,7 @@ public final class Breadcrumb implements JsonStream.Streamable {
Breadcrumb(@NonNull String name,
@NonNull BreadcrumbType type,
@NonNull Map<String, String> metadata) {
this.timestamp = DateUtils.toIso8601(new Date());
this.type = type;
this.metadata = metadata;
this.name = name;
this(name, type, new Date(), metadata);
}

Breadcrumb(@NonNull String name,
Expand All @@ -52,8 +50,8 @@ public final class Breadcrumb implements JsonStream.Streamable {
@NonNull Map<String, String> metadata) {
this.timestamp = DateUtils.toIso8601(captureDate);
this.type = type;
this.metadata = metadata;
this.name = name;
this.metadata = new HashMap<>(metadata);
}

@NonNull
Expand Down
12 changes: 9 additions & 3 deletions bugsnag-plugin-android-ndk/src/main/jni/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,24 @@ int bsg_populate_cpu_abi_from_map(JNIEnv *env, bsg_jni_cache *jni_cache,

void bsg_populate_crumb_metadata(JNIEnv *env, bugsnag_breadcrumb *crumb,
jobject metadata) {
if (metadata == NULL) {
return;
}

bsg_jni_cache *jni_cache = bsg_populate_jni_cache(env);
int size = (int)(*env)->CallIntMethod(env, metadata, jni_cache->map_size);
int map_size = (int)(*env)->CallIntMethod(env, metadata, jni_cache->map_size);
jobject keyset =
(*env)->CallObjectMethod(env, metadata, jni_cache->map_key_set);
jobject keylist = (*env)->NewObject(
env, jni_cache->arraylist, jni_cache->arraylist_init_with_obj, keyset);
for (int i = 0; i < size && i < sizeof(crumb->metadata); i++) {
size_t metadata_size = sizeof(crumb->metadata) / sizeof(bsg_char_metadata_pair);

for (int i = 0; i < map_size && i < metadata_size; i++) {
jstring _key = (*env)->CallObjectMethod(env, keylist,
jni_cache->arraylist_get, (jint)i);
jstring _value =
(*env)->CallObjectMethod(env, metadata, jni_cache->map_get, _key);
if (_value == NULL) {
if (_key == NULL || _value == NULL) {
(*env)->DeleteLocalRef(env, _key);
(*env)->DeleteLocalRef(env, _value);
} else {
Expand Down