fix(android): transcode mpv strings as standard UTF-8 across JNI
Emoji and other supplementary-plane characters in titles, file names, and subtitle paths were corrupted on the Android MPV path, and malformed bytes from mpv logs could abort under CheckJNI. NewStringUTF/GetStringUTFChars speak JNI's modified UTF-8, not the standard UTF-8 mpv produces and consumes; the native lead-byte filter and the Kotlin surrogate scrubber ran on the wrong side of that conversion and could not recover it. Both directions now go through UTF-16 (NewString/GetStringChars) with a small JNI-free transcoder that replaces malformed input with U+FFFD, the same policy as shared/cpp/sanitize_utf8.h on desktop. The header is covered by the Android host native test harness.
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/jni.h>
|
||||
@@ -137,16 +139,19 @@ jni_func(void, nativeCommand, jobjectArray jarray) {
|
||||
|
||||
const char* arguments[128] = {0};
|
||||
int len = env->GetArrayLength(jarray);
|
||||
if (len >= ARRAYLEN(arguments)) {
|
||||
if (len >= (int)ARRAYLEN(arguments)) {
|
||||
die("too many command arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
arguments[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(jarray, i), NULL);
|
||||
std::vector<std::string> storage;
|
||||
storage.reserve(len);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
jstring jarg = (jstring)env->GetObjectArrayElement(jarray, i);
|
||||
storage.push_back(java_string_to_utf8(env, jarg));
|
||||
arguments[i] = storage.back().c_str();
|
||||
env->DeleteLocalRef(jarg);
|
||||
}
|
||||
|
||||
mpv_command(g_mpv, arguments);
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(jarray, i), arguments[i]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user