[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master bb417daa703: Correct local reference leaks
From: |
Po Lu |
Subject: |
master bb417daa703: Correct local reference leaks |
Date: |
Wed, 4 Oct 2023 04:35:35 -0400 (EDT) |
branch: master
commit bb417daa703b0dd8871470ce53a40b16b1ca300b
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
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.
---
src/android.c | 45 +++++++++++++++++++++++++++++++++++++++------
src/android.h | 2 +-
src/androidmenu.c | 16 ++++++++--------
src/androidselect.c | 10 ++++++----
src/androidvfs.c | 8 ++++++--
5 files changed, 60 insertions(+), 21 deletions(-)
diff --git a/src/android.c b/src/android.c
index aa4033c676f..1424270e785 100644
--- a/src/android.c
+++ b/src/android.c
@@ -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,
diff --git a/src/android.h b/src/android.h
index d4605c11ad0..28d9d25930e 100644
--- a/src/android.h
+++ b/src/android.h
@@ -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);
diff --git a/src/androidmenu.c b/src/androidmenu.c
index ed26bdafa85..1f4d91b527d 100644
--- a/src/androidmenu.c
+++ b/src/androidmenu.c
@@ -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,
diff --git a/src/androidselect.c b/src/androidselect.c
index cf2265d4cf4..3f025351093 100644
--- a/src/androidselect.c
+++ b/src/androidselect.c
@@ -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
diff --git a/src/androidvfs.c b/src/androidvfs.c
index 0e5bbf8a13e..94c5d35ed2c 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master bb417daa703: Correct local reference leaks,
Po Lu <=