fix(jni): hand the native bridges standard UTF-8, not modified UTF-8 - #442
Open
xchacha20-poly1305 wants to merge 1 commit into
Open
xchacha20-poly1305 wants to merge 1 commit into
xchacha20-poly1305 wants to merge 1 commit into
Conversation
…ucleusFramework#441) GetStringUTFChars returns JNI's modified UTF-8, where a supplementary character arrives as its two UTF-16 surrogates encoded separately. All three bridges passed that straight to consumers that expect real UTF-8: MultiByteToWideChar on Windows turned an emoji label into mojibake, and sd-bus rejected the GetLayout reply with -EINVAL on Linux, which cost the whole menu rather than one item. Replace the per-bridge string handling with a shared jni_utf8_dup, which reads UTF-16 via GetStringChars and encodes it itself, mapping unpaired surrogates to U+FFFD so the result is always valid UTF-8. Labels, tooltips, titles, icon paths and shortcuts all go through it. Verified on GNOME: with the previous library GetLayout failed with -EINVAL for an emoji label; it now returns the layout with correct UTF-8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Collaborator
|
Thanks, I will check this |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #441.
Problem
All three JNI bridges read Java strings with
GetStringUTFChars, which returns JNI's modified UTF-8: a supplementary character (most emoji) comes back as its two UTF-16 surrogates encoded separately, 3 bytes each, instead of one 4-byte sequence. The bytes were then handed to consumers that expect real UTF-8:MultiByteToWideChar(CP_UTF8, ...)treats the surrogate sequences as invalid and substitutes replacement characters, so the label shows mojibake.svalues as UTF-8 and failsappend_menu_layoutwith-EINVAL, which fails the wholeGetLayoutcall, so the menu does not open at all.Fix
A shared
src/native/shared/jni_utf8.hprovidesjni_utf8_dup(), which reads UTF-16 withGetStringChars/GetStringLengthand encodes standard UTF-8 itself. Unpaired surrogates have no UTF-8 form and become U+FFFD, so the result is always valid UTF-8 whatever the Java string contains — sd-bus can never reject a label again.Every string entry point in the three bridges now goes through it: labels, tooltips, titles, icon paths and shortcut keys. On Windows this also replaces the
jni_strduphelper; on macOS it replaces theGetStringUTFChars+strduppairs and folds away the null checks, since the helper maps a nulljstringtoNULL.The three build configurations gained the
sharedinclude path.Tests
src/native/shared/test_jni_utf8.c(plusrun_jni_utf8_test.sh, wired into the Linux CI job next to the #436 test) exercises the helper against a stubJNIEnv, so it needs no JVM: ASCII, BMP CJK, a supplementary character in a label, two consecutive surrogate pairs, unpaired high and low surrogates, the 2- and 3-byte boundaries, and a nulljstring.End-to-end on GNOME, driving the built
libLinuxTray.sofrom a JNI harness with an emoji label and querying the menu over D-Bus:busctl ... com.canonical.dbusmenu GetLayout→Call failed: Invalid argument(-EINVAL), matching the reportlabel s "\360\237\232\200 Launch"— the correct 4-byte encoding of U+1F680The Windows and macOS bridges were not compiled here (Linux-only machine); the change is the same substitution on all three, and
tray_windows.calready converts withCP_UTF8and renders through theWAPIs, so correct input is all it needs.