From 511df960e4c1f1ac883f164a364b92fe685295f8 Mon Sep 17 00:00:00 2001 From: Chris Waldon Date: Tue, 30 Dec 2025 09:43:33 -0500 Subject: [PATCH] jni: release string characters in conversion to Go string This change should fix #13 by releasing the string buffer from the JVM after we convert the string to a Go string. However, I've been having a lot of trouble building the tests on Linux, and I've run out of time to keep messing with it. I'm posting this patch in the hope that someone else is better positioned to validate it. Please do not merge this unless you can verify that it works properly. Signed-off-by: Chris Waldon --- gojni.h | 1 + jni.c | 4 ++++ jni.go | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/gojni.h b/gojni.h index 9a1e065..ae552d6 100644 --- a/gojni.h +++ b/gojni.h @@ -15,6 +15,7 @@ __attribute__ ((visibility ("hidden"))) jfieldID _jni_GetFieldID(JNIEnv *env, jc __attribute__ ((visibility ("hidden"))) jfieldID _jni_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig); __attribute__ ((visibility ("hidden"))) jsize _jni_GetStringLength(JNIEnv *env, jstring str); __attribute__ ((visibility ("hidden"))) const jchar *_jni_GetStringChars(JNIEnv *env, jstring str); +__attribute__ ((visibility ("hidden"))) void _jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars); __attribute__ ((visibility ("hidden"))) jstring _jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len); __attribute__ ((visibility ("hidden"))) jboolean _jni_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2); __attribute__ ((visibility ("hidden"))) jboolean _jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass cls); diff --git a/jni.c b/jni.c index e66bd9f..c030eb2 100644 --- a/jni.c +++ b/jni.c @@ -78,6 +78,10 @@ const jchar *_jni_GetStringChars(JNIEnv *env, jstring str) { return (*env)->GetStringChars(env, str, NULL); } +void _jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars) { + (*env)->ReleaseStringChars(env, str, chars); +} + jstring _jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len) { return (*env)->NewString(env, unicodeChars, len); } diff --git a/jni.go b/jni.go index 6035453..dea3b93 100644 --- a/jni.go +++ b/jni.go @@ -411,6 +411,10 @@ func GoString(e Env, str String) string { } strlen := C._jni_GetStringLength(e.env, C.jstring(str)) chars := C._jni_GetStringChars(e.env, C.jstring(str)) + if chars == nil { + return "" + } + defer C._jni_ReleaseStringChars(e.env, C.jstring(str), chars) var utf16Chars []uint16 hdr := (*reflect.SliceHeader)(unsafe.Pointer(&utf16Chars)) hdr.Data = uintptr(unsafe.Pointer(chars)) -- 2.39.5