aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-10-04 16:33:05 +0800
committerPo Lu2023-10-04 16:33:05 +0800
commitbb417daa703b0dd8871470ce53a40b16b1ca300b (patch)
treee826d39aef4b622acfdc9c77a4b581dbab447fab /src
parentfbfdd1e0e3e67f765c6dbf9f61b5f913e55e004e (diff)
downloademacs-bb417daa703b0dd8871470ce53a40b16b1ca300b.tar.gz
emacs-bb417daa703b0dd8871470ce53a40b16b1ca300b.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/android.c45
-rw-r--r--src/android.h2
-rw-r--r--src/androidmenu.c16
-rw-r--r--src/androidselect.c10
-rw-r--r--src/androidvfs.c8
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)
5593} 5593}
5594 5594
5595/* Given a Lisp string TEXT, return a local reference to an equivalent 5595/* Given a Lisp string TEXT, return a local reference to an equivalent
5596 Java string. */ 5596 Java string. Each argument following TEXT should be NULL or a
5597 local reference that will be freed if creating the string fails,
5598 whereupon memory_full will also be signaled. */
5597 5599
5598jstring 5600jstring
5599android_build_string (Lisp_Object text) 5601android_build_string (Lisp_Object text, ...)
5600{ 5602{
5601 Lisp_Object encoded; 5603 Lisp_Object encoded;
5602 jstring string; 5604 jstring string;
5603 size_t nchars; 5605 size_t nchars;
5604 jchar *characters; 5606 jchar *characters;
5607 va_list ap;
5608 jobject object;
5609
5605 USE_SAFE_ALLOCA; 5610 USE_SAFE_ALLOCA;
5606 5611
5607 /* Directly encode TEXT if it contains no non-ASCII characters, or 5612 /* Directly encode TEXT if it contains no non-ASCII characters, or
@@ -5619,9 +5624,11 @@ android_build_string (Lisp_Object text)
5619 { 5624 {
5620 string = (*android_java_env)->NewStringUTF (android_java_env, 5625 string = (*android_java_env)->NewStringUTF (android_java_env,
5621 SSDATA (text)); 5626 SSDATA (text));
5622 android_exception_check ();
5623 SAFE_FREE ();
5624 5627
5628 if ((*android_java_env)->ExceptionCheck (android_java_env))
5629 goto error;
5630
5631 SAFE_FREE ();
5625 return string; 5632 return string;
5626 } 5633 }
5627 5634
@@ -5640,10 +5647,36 @@ android_build_string (Lisp_Object text)
5640 string 5647 string
5641 = (*android_java_env)->NewString (android_java_env, 5648 = (*android_java_env)->NewString (android_java_env,
5642 characters, nchars); 5649 characters, nchars);
5643 android_exception_check (); 5650
5651 if ((*android_java_env)->ExceptionCheck (android_java_env))
5652 goto error;
5644 5653
5645 SAFE_FREE (); 5654 SAFE_FREE ();
5646 return string; 5655 return string;
5656
5657 error:
5658 /* An exception arose while creating the string. When this
5659 transpires, an assumption is made that the error was induced by
5660 running out of memory. Delete each of the local references
5661 within AP. */
5662
5663 va_start (ap, text);
5664
5665 __android_log_print (ANDROID_LOG_WARN, __func__,
5666 "Possible out of memory error. "
5667 " The Java exception follows: ");
5668 /* Describe exactly what went wrong. */
5669 (*android_java_env)->ExceptionDescribe (android_java_env);
5670 (*android_java_env)->ExceptionClear (android_java_env);
5671
5672 /* Now remove each and every local reference provided after
5673 OBJECT. */
5674
5675 while ((object = va_arg (ap, jobject)))
5676 ANDROID_DELETE_LOCAL_REF (object);
5677
5678 va_end (ap);
5679 memory_full (0);
5647} 5680}
5648 5681
5649/* Do the same, except TEXT is constant string data in ASCII or 5682/* 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)
6154 Lisp_Object tem; 6187 Lisp_Object tem;
6155 const char *buffer; 6188 const char *buffer;
6156 6189
6157 string = android_build_string (url); 6190 string = android_build_string (url, NULL);
6158 value 6191 value
6159 = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env, 6192 = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env,
6160 emacs_service, 6193 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);
108extern void android_set_dont_accept_focus (android_window, bool); 108extern void android_set_dont_accept_focus (android_window, bool);
109 109
110extern int android_verify_jni_string (const char *); 110extern int android_verify_jni_string (const char *);
111extern jstring android_build_string (Lisp_Object); 111extern jstring android_build_string (Lisp_Object, ...);
112extern jstring android_build_jstring (const char *); 112extern jstring android_build_jstring (const char *);
113extern void android_exception_check (void); 113extern void android_exception_check (void);
114extern void android_exception_check_1 (jobject); 114extern 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,
278 278
279 title_string = NULL; 279 title_string = NULL;
280 if (STRINGP (title) && menu_items_n_panes < 2) 280 if (STRINGP (title) && menu_items_n_panes < 2)
281 title_string = android_build_string (title); 281 title_string = android_build_string (title, NULL);
282 282
283 /* Push the first local frame for the context menu. */ 283 /* Push the first local frame for the context menu. */
284 method = menu_class.create_context_menu; 284 method = menu_class.create_context_menu;
@@ -370,7 +370,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
370 pane_name = Fsubstring (pane_name, make_fixnum (1), Qnil); 370 pane_name = Fsubstring (pane_name, make_fixnum (1), Qnil);
371 371
372 /* Add the pane. */ 372 /* Add the pane. */
373 temp = android_build_string (pane_name); 373 temp = android_build_string (pane_name, NULL);
374 android_exception_check (); 374 android_exception_check ();
375 375
376 (*env)->CallNonvirtualVoidMethod (env, current_context_menu, 376 (*env)->CallNonvirtualVoidMethod (env, current_context_menu,
@@ -399,7 +399,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
399 { 399 {
400 /* This is a submenu. Add it. */ 400 /* This is a submenu. Add it. */
401 title_string = (!NILP (item_name) 401 title_string = (!NILP (item_name)
402 ? android_build_string (item_name) 402 ? android_build_string (item_name, NULL)
403 : NULL); 403 : NULL);
404 help_string = NULL; 404 help_string = NULL;
405 405
@@ -408,7 +408,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
408 408
409 if (android_get_current_api_level () >= 26 409 if (android_get_current_api_level () >= 26
410 && STRINGP (help)) 410 && STRINGP (help))
411 help_string = android_build_string (help); 411 help_string = android_build_string (help, NULL);
412 412
413 store = current_context_menu; 413 store = current_context_menu;
414 current_context_menu 414 current_context_menu
@@ -443,7 +443,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
443 /* Add this menu item with the appropriate state. */ 443 /* Add this menu item with the appropriate state. */
444 444
445 title_string = (!NILP (item_name) 445 title_string = (!NILP (item_name)
446 ? android_build_string (item_name) 446 ? android_build_string (item_name, NULL)
447 : NULL); 447 : NULL);
448 help_string = NULL; 448 help_string = NULL;
449 449
@@ -452,7 +452,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
452 452
453 if (android_get_current_api_level () >= 26 453 if (android_get_current_api_level () >= 26
454 && STRINGP (help)) 454 && STRINGP (help))
455 help_string = android_build_string (help); 455 help_string = android_build_string (help, NULL);
456 456
457 /* Determine whether or not to display a check box. */ 457 /* Determine whether or not to display a check box. */
458 458
@@ -686,7 +686,7 @@ android_dialog_show (struct frame *f, Lisp_Object title,
686 : android_build_jstring ("Question")); 686 : android_build_jstring ("Question"));
687 687
688 /* And the title. */ 688 /* And the title. */
689 java_title = android_build_string (title); 689 java_title = android_build_string (title, NULL);
690 690
691 /* Now create the dialog. */ 691 /* Now create the dialog. */
692 method = dialog_class.create_dialog; 692 method = dialog_class.create_dialog;
@@ -738,7 +738,7 @@ android_dialog_show (struct frame *f, Lisp_Object title,
738 } 738 }
739 739
740 /* Add the button. */ 740 /* Add the button. */
741 temp = android_build_string (item_name); 741 temp = android_build_string (item_name, NULL);
742 (*env)->CallNonvirtualVoidMethod (env, dialog, 742 (*env)->CallNonvirtualVoidMethod (env, dialog,
743 dialog_class.class, 743 dialog_class.class,
744 dialog_class.add_button, 744 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,
613 (long int) (boot_time.tv_sec / 2), id); 613 (long int) (boot_time.tv_sec / 2), id);
614 614
615 /* Encode all strings into their Java counterparts. */ 615 /* Encode all strings into their Java counterparts. */
616 title1 = android_build_string (title); 616 title1 = android_build_string (title, NULL);
617 body1 = android_build_string (body); 617 body1 = android_build_string (body, title1, NULL);
618 group1 = android_build_string (group); 618 group1 = android_build_string (group, body1, title1, NULL);
619 identifier1 = android_build_jstring (identifier); 619 identifier1
620 = (*android_java_env)->NewStringUTF (android_java_env, identifier);
621 android_exception_check_3 (title1, body1, group1);
620 622
621 /* Create the notification. */ 623 /* Create the notification. */
622 notification 624 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, ...)
3995 /* First, check for an exception. */ 3995 /* First, check for an exception. */
3996 3996
3997 if (!(*env)->ExceptionCheck (env)) 3997 if (!(*env)->ExceptionCheck (env))
3998 /* No exception has taken place. Return 0. */ 3998 {
3999 return 0; 3999 /* No exception has taken place. Return 0. */
4000 va_end (ap);
4001 return 0;
4002 }
4000 4003
4001 /* Print the exception. */ 4004 /* Print the exception. */
4002 (*env)->ExceptionDescribe (env); 4005 (*env)->ExceptionDescribe (env);
@@ -4045,6 +4048,7 @@ android_saf_exception_check (int n, ...)
4045 /* expression is still a local reference! */ 4048 /* expression is still a local reference! */
4046 ANDROID_DELETE_LOCAL_REF ((jobject) exception); 4049 ANDROID_DELETE_LOCAL_REF ((jobject) exception);
4047 errno = new_errno; 4050 errno = new_errno;
4051 va_end (ap);
4048 return 1; 4052 return 1;
4049} 4053}
4050 4054