mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Merge pull request #1501 from simophin/SES-2009-blinded-conversation
[SES-2009] Fix crashes on blinded conversation
This commit is contained in:
commit
c0912bbe6d
@ -1,5 +1,6 @@
|
|||||||
#include "config_base.h"
|
#include "config_base.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "jni_utils.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
@ -85,29 +86,34 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *en
|
|||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2(JNIEnv *env, jobject thiz,
|
Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2(JNIEnv *env, jobject thiz,
|
||||||
jobjectArray to_merge) {
|
jobjectArray to_merge) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
|
||||||
auto conf = ptrToConfigBase(env, thiz);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
size_t number = env->GetArrayLength(to_merge);
|
auto conf = ptrToConfigBase(env, thiz);
|
||||||
std::vector<std::pair<std::string,session::ustring>> configs = {};
|
size_t number = env->GetArrayLength(to_merge);
|
||||||
for (int i = 0; i < number; i++) {
|
std::vector<std::pair<std::string, session::ustring>> configs = {};
|
||||||
auto jElement = (jobject) env->GetObjectArrayElement(to_merge, i);
|
for (int i = 0; i < number; i++) {
|
||||||
auto pair = extractHashAndData(env, jElement);
|
auto jElement = (jobject) env->GetObjectArrayElement(to_merge, i);
|
||||||
configs.push_back(pair);
|
auto pair = extractHashAndData(env, jElement);
|
||||||
}
|
configs.push_back(pair);
|
||||||
auto returned = conf->merge(configs);
|
}
|
||||||
auto string_stack = util::build_string_stack(env, returned);
|
auto returned = conf->merge(configs);
|
||||||
return string_stack;
|
auto string_stack = util::build_string_stack(env, returned);
|
||||||
|
return string_stack;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_ConfigBase_merge__Lkotlin_Pair_2(JNIEnv *env, jobject thiz,
|
Java_network_loki_messenger_libsession_1util_ConfigBase_merge__Lkotlin_Pair_2(JNIEnv *env, jobject thiz,
|
||||||
jobject to_merge) {
|
jobject to_merge) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
|
||||||
auto conf = ptrToConfigBase(env, thiz);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
std::vector<std::pair<std::string, session::ustring>> configs = {extractHashAndData(env, to_merge)};
|
auto conf = ptrToConfigBase(env, thiz);
|
||||||
auto returned = conf->merge(configs);
|
std::vector<std::pair<std::string, session::ustring>> configs = {
|
||||||
auto string_stack = util::build_string_stack(env, returned);
|
extractHashAndData(env, to_merge)};
|
||||||
return string_stack;
|
auto returned = conf->merge(configs);
|
||||||
|
auto string_stack = util::build_string_stack(env, returned);
|
||||||
|
return string_stack;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
@ -1,100 +1,121 @@
|
|||||||
#include "contacts.h"
|
#include "contacts.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "jni_utils.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject thiz,
|
Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject thiz,
|
||||||
jstring session_id) {
|
jstring session_id) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
// If an exception is thrown, return nullptr
|
||||||
auto contacts = ptrToContacts(env, thiz);
|
return jni_utils::run_catching_cxx_exception_or<jobject>(
|
||||||
auto session_id_chars = env->GetStringUTFChars(session_id, nullptr);
|
[=]() -> jobject {
|
||||||
auto contact = contacts->get(session_id_chars);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
env->ReleaseStringUTFChars(session_id, session_id_chars);
|
auto contacts = ptrToContacts(env, thiz);
|
||||||
if (!contact) return nullptr;
|
auto session_id_chars = env->GetStringUTFChars(session_id, nullptr);
|
||||||
jobject j_contact = serialize_contact(env, contact.value());
|
auto contact = contacts->get(session_id_chars);
|
||||||
return j_contact;
|
env->ReleaseStringUTFChars(session_id, session_id_chars);
|
||||||
|
if (!contact) return nullptr;
|
||||||
|
jobject j_contact = serialize_contact(env, contact.value());
|
||||||
|
return j_contact;
|
||||||
|
},
|
||||||
|
[](const char *) -> jobject { return nullptr; }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_getOrConstruct(JNIEnv *env, jobject thiz,
|
Java_network_loki_messenger_libsession_1util_Contacts_getOrConstruct(JNIEnv *env, jobject thiz,
|
||||||
jstring session_id) {
|
jstring session_id) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
|
||||||
auto contacts = ptrToContacts(env, thiz);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
auto session_id_chars = env->GetStringUTFChars(session_id, nullptr);
|
auto contacts = ptrToContacts(env, thiz);
|
||||||
auto contact = contacts->get_or_construct(session_id_chars);
|
auto session_id_chars = env->GetStringUTFChars(session_id, nullptr);
|
||||||
env->ReleaseStringUTFChars(session_id, session_id_chars);
|
auto contact = contacts->get_or_construct(session_id_chars);
|
||||||
return serialize_contact(env, contact);
|
env->ReleaseStringUTFChars(session_id, session_id_chars);
|
||||||
|
return serialize_contact(env, contact);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_set(JNIEnv *env, jobject thiz,
|
Java_network_loki_messenger_libsession_1util_Contacts_set(JNIEnv *env, jobject thiz,
|
||||||
jobject contact) {
|
jobject contact) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
jni_utils::run_catching_cxx_exception_or_throws<void>(env, [=] {
|
||||||
auto contacts = ptrToContacts(env, thiz);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
auto contact_info = deserialize_contact(env, contact, contacts);
|
auto contacts = ptrToContacts(env, thiz);
|
||||||
contacts->set(contact_info);
|
auto contact_info = deserialize_contact(env, contact, contacts);
|
||||||
|
contacts->set(contact_info);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_erase(JNIEnv *env, jobject thiz,
|
Java_network_loki_messenger_libsession_1util_Contacts_erase(JNIEnv *env, jobject thiz,
|
||||||
jstring session_id) {
|
jstring session_id) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jboolean>(env, [=] {
|
||||||
auto contacts = ptrToContacts(env, thiz);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
auto session_id_chars = env->GetStringUTFChars(session_id, nullptr);
|
auto contacts = ptrToContacts(env, thiz);
|
||||||
|
auto session_id_chars = env->GetStringUTFChars(session_id, nullptr);
|
||||||
|
|
||||||
bool result = contacts->erase(session_id_chars);
|
bool result = contacts->erase(session_id_chars);
|
||||||
env->ReleaseStringUTFChars(session_id, session_id_chars);
|
env->ReleaseStringUTFChars(session_id, session_id_chars);
|
||||||
return result;
|
return result;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
extern "C"
|
extern "C"
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma ide diagnostic ignored "bugprone-reserved-identifier"
|
#pragma ide diagnostic ignored "bugprone-reserved-identifier"
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_00024Companion_newInstance___3B(JNIEnv *env,
|
Java_network_loki_messenger_libsession_1util_Contacts_00024Companion_newInstance___3B(JNIEnv *env,
|
||||||
jobject thiz,
|
jobject thiz,
|
||||||
jbyteArray ed25519_secret_key) {
|
jbyteArray ed25519_secret_key) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
|
||||||
auto secret_key = util::ustring_from_bytes(env, ed25519_secret_key);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
auto* contacts = new session::config::Contacts(secret_key, std::nullopt);
|
auto secret_key = util::ustring_from_bytes(env, ed25519_secret_key);
|
||||||
|
auto *contacts = new session::config::Contacts(secret_key, std::nullopt);
|
||||||
|
|
||||||
jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/Contacts");
|
jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/Contacts");
|
||||||
jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V");
|
jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V");
|
||||||
jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast<jlong>(contacts));
|
jobject newConfig = env->NewObject(contactsClass, constructor,
|
||||||
|
reinterpret_cast<jlong>(contacts));
|
||||||
|
|
||||||
return newConfig;
|
return newConfig;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_00024Companion_newInstance___3B_3B(
|
Java_network_loki_messenger_libsession_1util_Contacts_00024Companion_newInstance___3B_3B(
|
||||||
JNIEnv *env, jobject thiz, jbyteArray ed25519_secret_key, jbyteArray initial_dump) {
|
JNIEnv *env, jobject thiz, jbyteArray ed25519_secret_key, jbyteArray initial_dump) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
|
||||||
auto secret_key = util::ustring_from_bytes(env, ed25519_secret_key);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
auto initial = util::ustring_from_bytes(env, initial_dump);
|
auto secret_key = util::ustring_from_bytes(env, ed25519_secret_key);
|
||||||
|
auto initial = util::ustring_from_bytes(env, initial_dump);
|
||||||
|
|
||||||
auto* contacts = new session::config::Contacts(secret_key, initial);
|
auto *contacts = new session::config::Contacts(secret_key, initial);
|
||||||
|
|
||||||
jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/Contacts");
|
jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/Contacts");
|
||||||
jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V");
|
jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V");
|
||||||
jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast<jlong>(contacts));
|
jobject newConfig = env->NewObject(contactsClass, constructor,
|
||||||
|
reinterpret_cast<jlong>(contacts));
|
||||||
|
|
||||||
return newConfig;
|
return newConfig;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_Contacts_all(JNIEnv *env, jobject thiz) {
|
Java_network_loki_messenger_libsession_1util_Contacts_all(JNIEnv *env, jobject thiz) {
|
||||||
std::lock_guard lock{util::util_mutex_};
|
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
|
||||||
auto contacts = ptrToContacts(env, thiz);
|
std::lock_guard lock{util::util_mutex_};
|
||||||
jclass stack = env->FindClass("java/util/Stack");
|
auto contacts = ptrToContacts(env, thiz);
|
||||||
jmethodID init = env->GetMethodID(stack, "<init>", "()V");
|
jclass stack = env->FindClass("java/util/Stack");
|
||||||
jobject our_stack = env->NewObject(stack, init);
|
jmethodID init = env->GetMethodID(stack, "<init>", "()V");
|
||||||
jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
jobject our_stack = env->NewObject(stack, init);
|
||||||
for (const auto& contact : *contacts) {
|
jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
auto contact_obj = serialize_contact(env, contact);
|
for (const auto &contact: *contacts) {
|
||||||
env->CallObjectMethod(our_stack, push, contact_obj);
|
auto contact_obj = serialize_contact(env, contact);
|
||||||
}
|
env->CallObjectMethod(our_stack, push, contact_obj);
|
||||||
return our_stack;
|
}
|
||||||
|
return our_stack;
|
||||||
|
});
|
||||||
}
|
}
|
54
libsession-util/src/main/cpp/jni_utils.h
Normal file
54
libsession-util/src/main/cpp/jni_utils.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef SESSION_ANDROID_JNI_UTILS_H
|
||||||
|
#define SESSION_ANDROID_JNI_UTILS_H
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
namespace jni_utils {
|
||||||
|
/**
|
||||||
|
* Run a C++ function and catch any exceptions, throwing a Java exception if one is caught,
|
||||||
|
* and returning a default-constructed value of the specified type.
|
||||||
|
*
|
||||||
|
* @tparam RetT The return type of the function
|
||||||
|
* @tparam Func The function type
|
||||||
|
* @param f The function to run
|
||||||
|
* @param fallbackRun The function to run if an exception is caught. The optional exception message reference will be passed to this function.
|
||||||
|
* @return The return value of the function, or the return value of the fallback function if an exception was caught
|
||||||
|
*/
|
||||||
|
template<class RetT, class Func, class FallbackRun>
|
||||||
|
RetT run_catching_cxx_exception_or(Func f, FallbackRun fallbackRun) {
|
||||||
|
try {
|
||||||
|
return f();
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
return fallbackRun(e.what());
|
||||||
|
} catch (...) {
|
||||||
|
return fallbackRun(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a C++ function and catch any exceptions, throwing a Java exception if one is caught.
|
||||||
|
*
|
||||||
|
* @tparam RetT The return type of the function
|
||||||
|
* @tparam Func The function type
|
||||||
|
* @param env The JNI environment
|
||||||
|
* @param f The function to run
|
||||||
|
* @return The return value of the function, or a default-constructed value of the specified type if an exception was caught
|
||||||
|
*/
|
||||||
|
template<class RetT, class Func>
|
||||||
|
RetT run_catching_cxx_exception_or_throws(JNIEnv *env, Func f) {
|
||||||
|
return run_catching_cxx_exception_or<RetT>(f, [env](const char *msg) {
|
||||||
|
jclass exceptionClass = env->FindClass("java/lang/RuntimeException");
|
||||||
|
if (msg) {
|
||||||
|
auto formatted_message = std::string("libsession: C++ exception: ") + msg;
|
||||||
|
env->ThrowNew(exceptionClass, formatted_message.c_str());
|
||||||
|
} else {
|
||||||
|
env->ThrowNew(exceptionClass, "libsession: Unknown C++ exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
return RetT();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SESSION_ANDROID_JNI_UTILS_H
|
Loading…
x
Reference in New Issue
Block a user