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.
This commit is contained in:
parent
30f83e3093
commit
d679f9e388
1 changed files with 28 additions and 6 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue