From 6be8476f90986687dc7c16a018196ce0db490fd9 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:38:49 +0300 Subject: [PATCH] desktop: decoding utf8 (#2774) --- .../src/commonMain/cpp/desktop/simplex-api.c | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/cpp/desktop/simplex-api.c b/apps/multiplatform/common/src/commonMain/cpp/desktop/simplex-api.c index 2f7299393c..2c3e123fd5 100644 --- a/apps/multiplatform/common/src/commonMain/cpp/desktop/simplex-api.c +++ b/apps/multiplatform/common/src/commonMain/cpp/desktop/simplex-api.c @@ -1,4 +1,5 @@ #include +#include // from the RTS void hs_init(int * argc, char **argv[]); @@ -30,13 +31,35 @@ extern char *chat_parse_markdown(const char *str); extern char *chat_parse_server(const char *str); extern char *chat_password_hash(const char *pwd, const char *salt); + +// As a reference: https://stackoverflow.com/a/60002045 +jstring correct_string_utf8(JNIEnv *env, char *string) { + jobject bb = (*env)->NewDirectByteBuffer(env, (void *)string, strlen(string)); + jclass cls_charset = (*env)->FindClass(env, "java/nio/charset/Charset"); + jmethodID mid_charset_forName = (*env)->GetStaticMethodID(env, cls_charset, "forName", "(Ljava/lang/String;)Ljava/nio/charset/Charset;"); + jobject charset = (*env)->CallStaticObjectMethod(env, cls_charset, mid_charset_forName, (*env)->NewStringUTF(env, "UTF-8")); + + jmethodID mid_decode = (*env)->GetMethodID(env, cls_charset, "decode", "(Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;"); + jobject cb = (*env)->CallObjectMethod(env, charset, mid_decode, bb); + + jclass cls_char_buffer = (*env)->FindClass(env, "java/nio/CharBuffer"); + jmethodID mid_to_string = (*env)->GetMethodID(env, cls_char_buffer, "toString", "()Ljava/lang/String;"); + jstring res = (*env)->CallObjectMethod(env, cb, mid_to_string); + + (*env)->DeleteLocalRef(env, bb); + (*env)->DeleteLocalRef(env, charset); + (*env)->DeleteLocalRef(env, cb); + return res; +} + + JNIEXPORT jobjectArray JNICALL Java_chat_simplex_common_platform_CoreKt_chatMigrateInit(JNIEnv *env, jclass clazz, jstring dbPath, jstring dbKey, jstring confirm) { const char *_dbPath = (*env)->GetStringUTFChars(env, dbPath, JNI_FALSE); const char *_dbKey = (*env)->GetStringUTFChars(env, dbKey, JNI_FALSE); const char *_confirm = (*env)->GetStringUTFChars(env, confirm, JNI_FALSE); jlong _ctrl = (jlong) 0; - jstring res = (*env)->NewStringUTF(env, chat_migrate_init(_dbPath, _dbKey, _confirm, &_ctrl)); + jstring res = correct_string_utf8(env, chat_migrate_init(_dbPath, _dbKey, _confirm, &_ctrl)); (*env)->ReleaseStringUTFChars(env, dbPath, _dbPath); (*env)->ReleaseStringUTFChars(env, dbKey, _dbKey); (*env)->ReleaseStringUTFChars(env, dbKey, _confirm); @@ -56,25 +79,25 @@ Java_chat_simplex_common_platform_CoreKt_chatMigrateInit(JNIEnv *env, jclass cla JNIEXPORT jstring JNICALL Java_chat_simplex_common_platform_CoreKt_chatSendCmd(JNIEnv *env, jclass clazz, jlong controller, jstring msg) { const char *_msg = (*env)->GetStringUTFChars(env, msg, JNI_FALSE); - jstring res = (*env)->NewStringUTF(env, chat_send_cmd((void*)controller, _msg)); + jstring res = correct_string_utf8(env, chat_send_cmd((void*)controller, _msg)); (*env)->ReleaseStringUTFChars(env, msg, _msg); return res; } JNIEXPORT jstring JNICALL Java_chat_simplex_common_platform_CoreKt_chatRecvMsg(JNIEnv *env, jclass clazz, jlong controller) { - return (*env)->NewStringUTF(env, chat_recv_msg((void*)controller)); + return correct_string_utf8(env, chat_recv_msg((void*)controller)); } JNIEXPORT jstring JNICALL Java_chat_simplex_common_platform_CoreKt_chatRecvMsgWait(JNIEnv *env, jclass clazz, jlong controller, jint wait) { - return (*env)->NewStringUTF(env, chat_recv_msg_wait((void*)controller, wait)); + return correct_string_utf8(env, chat_recv_msg_wait((void*)controller, wait)); } JNIEXPORT jstring JNICALL Java_chat_simplex_common_platform_CoreKt_chatParseMarkdown(JNIEnv *env, jclass clazz, jstring str) { const char *_str = (*env)->GetStringUTFChars(env, str, JNI_FALSE); - jstring res = (*env)->NewStringUTF(env, chat_parse_markdown(_str)); + jstring res = correct_string_utf8(env, chat_parse_markdown(_str)); (*env)->ReleaseStringUTFChars(env, str, _str); return res; } @@ -82,7 +105,7 @@ Java_chat_simplex_common_platform_CoreKt_chatParseMarkdown(JNIEnv *env, jclass c JNIEXPORT jstring JNICALL Java_chat_simplex_common_platform_CoreKt_chatParseServer(JNIEnv *env, jclass clazz, jstring str) { const char *_str = (*env)->GetStringUTFChars(env, str, JNI_FALSE); - jstring res = (*env)->NewStringUTF(env, chat_parse_server(_str)); + jstring res = correct_string_utf8(env, chat_parse_server(_str)); (*env)->ReleaseStringUTFChars(env, str, _str); return res; } @@ -91,7 +114,7 @@ JNIEXPORT jstring JNICALL Java_chat_simplex_common_platform_CoreKt_chatPasswordHash(JNIEnv *env, jclass clazz, jstring pwd, jstring salt) { const char *_pwd = (*env)->GetStringUTFChars(env, pwd, JNI_FALSE); const char *_salt = (*env)->GetStringUTFChars(env, salt, JNI_FALSE); - jstring res = (*env)->NewStringUTF(env, chat_password_hash(_pwd, _salt)); + jstring res = correct_string_utf8(env, chat_password_hash(_pwd, _salt)); (*env)->ReleaseStringUTFChars(env, pwd, _pwd); (*env)->ReleaseStringUTFChars(env, salt, _salt); return res;