[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master d679f9e388c: Fix leak when quit arrives during incremental select
From: |
Po Lu |
Subject: |
master d679f9e388c: Fix leak when quit arrives during incremental selection transfer |
Date: |
Sun, 2 Jul 2023 23:45:36 -0400 (EDT) |
branch: master
commit d679f9e388cde367d8d0c2e438b62a16ec1aca67
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Fix leak when quit arrives during incremental selection transfer
* src/xselect.c (x_free_selection_data): New function.
(x_get_window_property_as_lisp_data): Free `data' reliably
if receive_incremental_selection quits.
---
src/xselect.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/src/xselect.c b/src/xselect.c
index 40be6d4c00c..c38a1f8b6a9 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1989,9 +1989,22 @@ receive_incremental_selection (struct x_display_info
*dpyinfo,
}
+
+/* Free the selection data allocated inside *DATA, which is actually a
+ pointer to unsigned char *. */
+
+static void
+x_free_selection_data (void *data)
+{
+ unsigned char **ptr;
+
+ ptr = data;
+ xfree (*ptr);
+}
+
/* Fetch a value from property PROPERTY of X window WINDOW on display
- DISPLAY. TARGET_TYPE and SELECTION_ATOM are used in error message
- if this fails. */
+ DISPLAY. TARGET_TYPE and SELECTION_ATOM are used in the error
+ message signaled if this fails. */
static Lisp_Object
x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo,
@@ -2007,6 +2020,7 @@ x_get_window_property_as_lisp_data (struct x_display_info
*dpyinfo,
ptrdiff_t bytes = 0, array_bytes;
Lisp_Object val;
Display *display = dpyinfo->display;
+ specpdl_ref count;
/* array_bytes is only used as an argument to xpalloc. The actual
size of the data inside the buffer is inside bytes. */
@@ -2042,6 +2056,13 @@ x_get_window_property_as_lisp_data (struct
x_display_info *dpyinfo,
}
}
+ /* Make sure DATA is freed even if `receive_incremental_connection'
+ quits. Use xfree, not XFree, because x_get_window_property calls
+ xmalloc itself. */
+
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (x_free_selection_data, &data);
+
if (!for_multiple && actual_type == dpyinfo->Xatom_INCR)
{
/* That wasn't really the data, just the beginning. */
@@ -2051,6 +2072,9 @@ x_get_window_property_as_lisp_data (struct x_display_info
*dpyinfo,
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
xfree (data);
+
+ /* In case quitting happens below. */
+ data = NULL;
unblock_input ();
/* Clear bytes again. Previously, receive_incremental_selection
@@ -2077,10 +2101,8 @@ x_get_window_property_as_lisp_data (struct
x_display_info *dpyinfo,
val = selection_data_to_lisp_data (dpyinfo, data, bytes,
actual_type, actual_format);
- /* Use xfree, not XFree, because x_get_window_property
- calls xmalloc itself. */
- xfree (data);
- return val;
+ /* This will also free `data'. */
+ return unbind_to (count, val);
}
/* These functions convert from the selection data read from the server into
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master d679f9e388c: Fix leak when quit arrives during incremental selection transfer,
Po Lu <=