Correct local reference leaks
* src/android.c (android_build_string): Accept a list of local references to destroy upon an allocation failure, facilitating the proper deallocation of local references in such situations. (android_browse_url): Revise for new calling convention. * src/android.h (android_build_string): Update declaration correspondingly. * src/androidmenu.c (android_menu_show, android_dialog_show): Revise for new calling convention. * src/androidselect.c (android_notifications_notify_1): Supply each successive local reference to android_build_string as notification text is being encoded. * src/androidvfs.c (android_saf_exception_check): Introduce absent va_end.
This commit is contained in:
parent
fbfdd1e0e3
commit
bb417daa70
5 changed files with 60 additions and 21 deletions
|
@ -5593,15 +5593,20 @@ android_verify_jni_string (const char *name)
|
|||
}
|
||||
|
||||
/* Given a Lisp string TEXT, return a local reference to an equivalent
|
||||
Java string. */
|
||||
Java string. Each argument following TEXT should be NULL or a
|
||||
local reference that will be freed if creating the string fails,
|
||||
whereupon memory_full will also be signaled. */
|
||||
|
||||
jstring
|
||||
android_build_string (Lisp_Object text)
|
||||
android_build_string (Lisp_Object text, ...)
|
||||
{
|
||||
Lisp_Object encoded;
|
||||
jstring string;
|
||||
size_t nchars;
|
||||
jchar *characters;
|
||||
va_list ap;
|
||||
jobject object;
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* Directly encode TEXT if it contains no non-ASCII characters, or
|
||||
|
@ -5619,9 +5624,11 @@ android_build_string (Lisp_Object text)
|
|||
{
|
||||
string = (*android_java_env)->NewStringUTF (android_java_env,
|
||||
SSDATA (text));
|
||||
android_exception_check ();
|
||||
SAFE_FREE ();
|
||||
|
||||
if ((*android_java_env)->ExceptionCheck (android_java_env))
|
||||
goto error;
|
||||
|
||||
SAFE_FREE ();
|
||||
return string;
|
||||
}
|
||||
|
||||
|
@ -5640,10 +5647,36 @@ android_build_string (Lisp_Object text)
|
|||
string
|
||||
= (*android_java_env)->NewString (android_java_env,
|
||||
characters, nchars);
|
||||
android_exception_check ();
|
||||
|
||||
if ((*android_java_env)->ExceptionCheck (android_java_env))
|
||||
goto error;
|
||||
|
||||
SAFE_FREE ();
|
||||
return string;
|
||||
|
||||
error:
|
||||
/* An exception arose while creating the string. When this
|
||||
transpires, an assumption is made that the error was induced by
|
||||
running out of memory. Delete each of the local references
|
||||
within AP. */
|
||||
|
||||
va_start (ap, text);
|
||||
|
||||
__android_log_print (ANDROID_LOG_WARN, __func__,
|
||||
"Possible out of memory error. "
|
||||
" The Java exception follows: ");
|
||||
/* Describe exactly what went wrong. */
|
||||
(*android_java_env)->ExceptionDescribe (android_java_env);
|
||||
(*android_java_env)->ExceptionClear (android_java_env);
|
||||
|
||||
/* Now remove each and every local reference provided after
|
||||
OBJECT. */
|
||||
|
||||
while ((object = va_arg (ap, jobject)))
|
||||
ANDROID_DELETE_LOCAL_REF (object);
|
||||
|
||||
va_end (ap);
|
||||
memory_full (0);
|
||||
}
|
||||
|
||||
/* Do the same, except TEXT is constant string data in ASCII or
|
||||
|
@ -6154,7 +6187,7 @@ android_browse_url (Lisp_Object url, Lisp_Object send)
|
|||
Lisp_Object tem;
|
||||
const char *buffer;
|
||||
|
||||
string = android_build_string (url);
|
||||
string = android_build_string (url, NULL);
|
||||
value
|
||||
= (*android_java_env)->CallNonvirtualObjectMethod (android_java_env,
|
||||
emacs_service,
|
||||
|
|
|
@ -108,7 +108,7 @@ extern void android_set_dont_focus_on_map (android_window, bool);
|
|||
extern void android_set_dont_accept_focus (android_window, bool);
|
||||
|
||||
extern int android_verify_jni_string (const char *);
|
||||
extern jstring android_build_string (Lisp_Object);
|
||||
extern jstring android_build_string (Lisp_Object, ...);
|
||||
extern jstring android_build_jstring (const char *);
|
||||
extern void android_exception_check (void);
|
||||
extern void android_exception_check_1 (jobject);
|
||||
|
|
|
@ -278,7 +278,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
|
||||
title_string = NULL;
|
||||
if (STRINGP (title) && menu_items_n_panes < 2)
|
||||
title_string = android_build_string (title);
|
||||
title_string = android_build_string (title, NULL);
|
||||
|
||||
/* Push the first local frame for the context menu. */
|
||||
method = menu_class.create_context_menu;
|
||||
|
@ -370,7 +370,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
pane_name = Fsubstring (pane_name, make_fixnum (1), Qnil);
|
||||
|
||||
/* Add the pane. */
|
||||
temp = android_build_string (pane_name);
|
||||
temp = android_build_string (pane_name, NULL);
|
||||
android_exception_check ();
|
||||
|
||||
(*env)->CallNonvirtualVoidMethod (env, current_context_menu,
|
||||
|
@ -399,7 +399,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
{
|
||||
/* This is a submenu. Add it. */
|
||||
title_string = (!NILP (item_name)
|
||||
? android_build_string (item_name)
|
||||
? android_build_string (item_name, NULL)
|
||||
: NULL);
|
||||
help_string = NULL;
|
||||
|
||||
|
@ -408,7 +408,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
|
||||
if (android_get_current_api_level () >= 26
|
||||
&& STRINGP (help))
|
||||
help_string = android_build_string (help);
|
||||
help_string = android_build_string (help, NULL);
|
||||
|
||||
store = current_context_menu;
|
||||
current_context_menu
|
||||
|
@ -443,7 +443,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
/* Add this menu item with the appropriate state. */
|
||||
|
||||
title_string = (!NILP (item_name)
|
||||
? android_build_string (item_name)
|
||||
? android_build_string (item_name, NULL)
|
||||
: NULL);
|
||||
help_string = NULL;
|
||||
|
||||
|
@ -452,7 +452,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
|
||||
if (android_get_current_api_level () >= 26
|
||||
&& STRINGP (help))
|
||||
help_string = android_build_string (help);
|
||||
help_string = android_build_string (help, NULL);
|
||||
|
||||
/* Determine whether or not to display a check box. */
|
||||
|
||||
|
@ -686,7 +686,7 @@ android_dialog_show (struct frame *f, Lisp_Object title,
|
|||
: android_build_jstring ("Question"));
|
||||
|
||||
/* And the title. */
|
||||
java_title = android_build_string (title);
|
||||
java_title = android_build_string (title, NULL);
|
||||
|
||||
/* Now create the dialog. */
|
||||
method = dialog_class.create_dialog;
|
||||
|
@ -738,7 +738,7 @@ android_dialog_show (struct frame *f, Lisp_Object title,
|
|||
}
|
||||
|
||||
/* Add the button. */
|
||||
temp = android_build_string (item_name);
|
||||
temp = android_build_string (item_name, NULL);
|
||||
(*env)->CallNonvirtualVoidMethod (env, dialog,
|
||||
dialog_class.class,
|
||||
dialog_class.add_button,
|
||||
|
|
|
@ -613,10 +613,12 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
|
|||
(long int) (boot_time.tv_sec / 2), id);
|
||||
|
||||
/* Encode all strings into their Java counterparts. */
|
||||
title1 = android_build_string (title);
|
||||
body1 = android_build_string (body);
|
||||
group1 = android_build_string (group);
|
||||
identifier1 = android_build_jstring (identifier);
|
||||
title1 = android_build_string (title, NULL);
|
||||
body1 = android_build_string (body, title1, NULL);
|
||||
group1 = android_build_string (group, body1, title1, NULL);
|
||||
identifier1
|
||||
= (*android_java_env)->NewStringUTF (android_java_env, identifier);
|
||||
android_exception_check_3 (title1, body1, group1);
|
||||
|
||||
/* Create the notification. */
|
||||
notification
|
||||
|
|
|
@ -3995,8 +3995,11 @@ android_saf_exception_check (int n, ...)
|
|||
/* First, check for an exception. */
|
||||
|
||||
if (!(*env)->ExceptionCheck (env))
|
||||
/* No exception has taken place. Return 0. */
|
||||
return 0;
|
||||
{
|
||||
/* No exception has taken place. Return 0. */
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print the exception. */
|
||||
(*env)->ExceptionDescribe (env);
|
||||
|
@ -4045,6 +4048,7 @@ android_saf_exception_check (int n, ...)
|
|||
/* expression is still a local reference! */
|
||||
ANDROID_DELETE_LOCAL_REF ((jobject) exception);
|
||||
errno = new_errno;
|
||||
va_end (ap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue