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

[RKOTLIN-1089] Guard decoding issues when core logs invalid utf-8 messages #1792

Merged
merged 1 commit into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* None.

### Fixed
* Fix crashes when core tries to log invalid utf-8 messages. (Issue [#1760](https://github.com/realm/realm-kotlin/issues/1760) [RKOTLIN-1089](https://jira.mongodb.org/browse/RKOTLIN-1089)).
* [Sync] Fatal sync exceptions are now thrown as `UnrecoverableSyncException`. (Issue [#1767](https://github.com/realm/realm-kotlin/issues/1767) [RKOTLIN-1096](https://jira.mongodb.org/browse/RKOTLIN-1096)).
* [Sync] Fix `NullPointerException` in `SubscriptionSet.waitForSynchronization`. (Issue [#1777](https://github.com/realm/realm-kotlin/issues/1777) [RKOTLIN-1102](https://jira.mongodb.org/browse/RKOTLIN-1102)).

Expand Down
7 changes: 3 additions & 4 deletions packages/cinterop/src/jvm/jni/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ static std::string string_to_hex(const std::string& message, realm::StringData&
ret << "error_code = " << error_code << "; ";
ret << "retcode = " << retcode << "; ";
ret << "StringData.size = " << str.size() << "; ";
ret << "StringData.data = " << str << "; ";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not printing data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This string_to_hex is only used to make a hex-dump of the data when we fail to decode it from UTF-8. So don't think it makes sense to include the non-decodable string itself. The result of this method is used as the message of an exception and we cannot pass that on to the JVM if the message itself is not valid unicode.

ret << "StringData as hex = ";
ret << "StringData as hex =";
for (std::string::size_type i = 0; i < str.size(); ++i)
ret << " 0x" << std::hex << std::setfill('0') << std::setw(2) << (int)s[i];
ret << "; ";
ret << "in_begin = " << in_begin << "; ";
ret << "in_end = " << in_end << "; ";
ret << "in_begin = " << (void*) in_begin << "; ";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why casting to opaque pointer?

Copy link
Contributor Author

@rorbech rorbech Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If treating in_begin and in_end as char * they will be considered as 0-terminated strings and printed to the stream ... in which case we end up including the invalid UTF-8 bytes in the message - Just as for ret << "StringData.data = " << str << "; ";. Want to avoid having invalid unicode in the exception message as spelled out in #1792 (comment). Just including the pointers to give some insights if we were to try to understand and reproduce an issue based on one of these exceptions.

ret << "in_end = " << (void*) in_end << "; ";
ret << "out_curr = " << out_curr << "; ";
ret << "out_end = " << out_end << ";";
return ret.str();
Expand Down
10 changes: 9 additions & 1 deletion packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,15 @@ realm_set_log_callback([](void *userdata, const char *category, realm_log_level_
"(SLjava/lang/String;Ljava/lang/String;)V");

push_local_frame(jenv, 2);
jenv->CallVoidMethod(log_callback, log_method, java_level, to_jstring(jenv, category), to_jstring(jenv, message));
jstring j_message = NULL;
try {
j_message = to_jstring(jenv, message);
} catch (RuntimeError exception) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you observe this on Android & JVM?

Copy link
Contributor Author

@rorbech rorbech Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is on both platforms

std::ostringstream ret;
ret << "Invalid data: " << exception.reason();
j_message = to_jstring(jenv, ret.str());
}
jenv->CallVoidMethod(log_callback, log_method, java_level, to_jstring(jenv, category), j_message);
jni_check_exception(jenv);
jenv->PopLocalFrame(NULL);
},
Expand Down
Loading