From 0ce154bac6e5ba588f059564dd724bc042e59f8b Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 7 Jul 2024 10:19:31 +0800 Subject: [PATCH] Correct JNI string error checking and miscellaneous corrections * src/android-emacs.c (main): Do not attempt to load the bootstrap class path, which is redundant on all Android releases. * src/android.c (initEmacs, android_browse_url): Do not assume exceptions will be raised if GetStringUTFChars fails. Decode Android JNI strings as Qandroid_jni. * src/androidvfs.c (android_saf_check_nonnull): New function. (android_saf_new_mkdir): Likewise. (cherry picked from commit 99e510977b22ca60e48b2af70a3c2cdbd90b2b01) --- src/android-emacs.c | 63 +++------------------------------------------ src/android.c | 10 ++++--- src/androidvfs.c | 33 +++++++++++++++++++++++- 3 files changed, 42 insertions(+), 64 deletions(-) diff --git a/src/android-emacs.c b/src/android-emacs.c index 5a43445612a..d68734da1bd 100644 --- a/src/android-emacs.c +++ b/src/android-emacs.c @@ -52,49 +52,6 @@ main (int argc, char **argv) args[0] = (char *) "/system/bin/app_process"; #endif /* __x86_64__ || __aarch64__ || __mips64 */ - /* Machines with ART require the boot classpath to be manually - specified. Machines with Dalvik however refuse to do so, as they - open the jars inside the BOOTCLASSPATH environment variable at - startup, resulting in the following crash: - - W/dalvikvm( 1608): Refusing to reopen boot DEX - '/system/framework/core.jar' - W/dalvikvm( 1608): Refusing to reopen boot DEX - '/system/framework/bouncycastle.jar' - E/dalvikvm( 1608): Too many exceptions during init (failed on - 'Ljava/io/IOException;' 'Re-opening BOOTCLASSPATH DEX files is - not allowed') - E/dalvikvm( 1608): VM aborting */ - -#if HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL - if (android_get_device_api_level () < 21) - { - bootclasspath = NULL; - goto skip_setup; - } -#else /* !HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL */ - if (__ANDROID_API__ < 21) - { - bootclasspath = NULL; - goto skip_setup; - } -#endif /* HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL */ - - /* Next, obtain the boot class path. */ - bootclasspath = getenv ("BOOTCLASSPATH"); - - if (!bootclasspath) - { - fprintf (stderr, "The BOOTCLASSPATH environment variable" - " is not set. As a result, Emacs does not know" - " how to start app_process.\n" - "This is likely a change in the Android platform." - " Please report this to bug-gnu-emacs@gnu.org.\n"); - return 1; - } - - skip_setup: - /* And the Emacs class path. */ emacs_class_path = getenv ("EMACS_CLASS_PATH"); @@ -115,23 +72,11 @@ main (int argc, char **argv) if (ld_library_path) setenv ("LD_LIBRARY_PATH", ld_library_path, 1); - if (bootclasspath) + if (asprintf (&bootclasspath, "-Djava.class.path=%s", + emacs_class_path) < 0) { - if (asprintf (&bootclasspath, "-Djava.class.path=%s:%s", - bootclasspath, emacs_class_path) < 0) - { - perror ("asprintf"); - return 1; - } - } - else - { - if (asprintf (&bootclasspath, "-Djava.class.path=%s", - emacs_class_path) < 0) - { - perror ("asprintf"); - return 1; - } + perror ("asprintf"); + return 1; } args[1] = bootclasspath; diff --git a/src/android.c b/src/android.c index 3c0e3ee1558..f90ebc04925 100644 --- a/src/android.c +++ b/src/android.c @@ -2019,6 +2019,8 @@ NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv, c_argument = (*env)->GetStringUTFChars (env, (jstring) dump_file_object, NULL); + if (!c_argument) + emacs_abort (); /* Copy the Java string data once. */ dump_file = strdup (c_argument); @@ -6497,18 +6499,18 @@ android_browse_url (Lisp_Object url, Lisp_Object send) buffer = (*android_java_env)->GetStringUTFChars (android_java_env, (jstring) value, NULL); - android_exception_check_1 (value); + android_exception_check_nonnull ((void *) buffer, value); /* Otherwise, build the string describing the error. */ - tem = build_string_from_utf8 (buffer); + tem = build_unibyte_string (buffer); (*android_java_env)->ReleaseStringUTFChars (android_java_env, (jstring) value, buffer); - /* And return it. */ + /* And decode and return the same. */ ANDROID_DELETE_LOCAL_REF (value); - return tem; + return code_convert_string_norecord (tem, Qandroid_jni, false); } /* Tell the system to restart Emacs in a short amount of time, and diff --git a/src/androidvfs.c b/src/androidvfs.c index 346eb639b11..2427708be34 100644 --- a/src/androidvfs.c +++ b/src/androidvfs.c @@ -3162,6 +3162,37 @@ android_saf_exception_check (int n, ...) return 1; } +/* Verify that OBJECT is non-NULL. If NULL, free each of the N local + references given as arguments, and clear exceptions. + + Value is 1 if it be NULL, 0 otherwise. */ + +static int +android_saf_check_nonnull (jobject object, int n, ...) +{ + va_list ap; + + if (object) + return 0; + + va_start (ap, n); + + /* Clear the active exception, making it safe to subsequently call + other JNI functions. */ + (*android_java_env)->ExceptionClear (android_java_env); + + /* Delete each of the N arguments. */ + + while (n > 0) + { + ANDROID_DELETE_LOCAL_REF (va_arg (ap, jobject)); + n--; + } + + va_end (ap); + return 1; +} + /* Content authority-based vnode implementation. @@ -6428,7 +6459,7 @@ android_saf_new_mkdir (struct android_vnode *vnode, mode_t mode) new_doc_id = (*android_java_env)->GetStringUTFChars (android_java_env, new_id, NULL); - if (android_saf_exception_check (3, name, id, uri)) + if (android_saf_check_nonnull (new_doc_id, 3, name, id, uri)) return -1; xfree (vp->document_id); -- 2.39.2