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.
This commit is contained in:
Po Lu 2024-07-07 10:19:31 +08:00
parent bbe95a8cea
commit 99e510977b
3 changed files with 42 additions and 64 deletions

View file

@ -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;

View file

@ -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

View file

@ -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);