aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-07-03 11:45:04 +0800
committerPo Lu2023-07-03 11:45:04 +0800
commitd679f9e388cde367d8d0c2e438b62a16ec1aca67 (patch)
tree5c5ce404fb04a7a7183ff9dc11996a90a9764af2 /src
parent30f83e30932f2b0f523b66e5dcf1b8fec54ec1f7 (diff)
downloademacs-d679f9e388cde367d8d0c2e438b62a16ec1aca67.tar.gz
emacs-d679f9e388cde367d8d0c2e438b62a16ec1aca67.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/xselect.c34
1 files 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,
1989} 1989}
1990 1990
1991 1991
1992
1993/* Free the selection data allocated inside *DATA, which is actually a
1994 pointer to unsigned char *. */
1995
1996static void
1997x_free_selection_data (void *data)
1998{
1999 unsigned char **ptr;
2000
2001 ptr = data;
2002 xfree (*ptr);
2003}
2004
1992/* Fetch a value from property PROPERTY of X window WINDOW on display 2005/* Fetch a value from property PROPERTY of X window WINDOW on display
1993 DISPLAY. TARGET_TYPE and SELECTION_ATOM are used in error message 2006 DISPLAY. TARGET_TYPE and SELECTION_ATOM are used in the error
1994 if this fails. */ 2007 message signaled if this fails. */
1995 2008
1996static Lisp_Object 2009static Lisp_Object
1997x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, 2010x_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,
2007 ptrdiff_t bytes = 0, array_bytes; 2020 ptrdiff_t bytes = 0, array_bytes;
2008 Lisp_Object val; 2021 Lisp_Object val;
2009 Display *display = dpyinfo->display; 2022 Display *display = dpyinfo->display;
2023 specpdl_ref count;
2010 2024
2011 /* array_bytes is only used as an argument to xpalloc. The actual 2025 /* array_bytes is only used as an argument to xpalloc. The actual
2012 size of the data inside the buffer is inside bytes. */ 2026 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,
2042 } 2056 }
2043 } 2057 }
2044 2058
2059 /* Make sure DATA is freed even if `receive_incremental_connection'
2060 quits. Use xfree, not XFree, because x_get_window_property calls
2061 xmalloc itself. */
2062
2063 count = SPECPDL_INDEX ();
2064 record_unwind_protect_ptr (x_free_selection_data, &data);
2065
2045 if (!for_multiple && actual_type == dpyinfo->Xatom_INCR) 2066 if (!for_multiple && actual_type == dpyinfo->Xatom_INCR)
2046 { 2067 {
2047 /* That wasn't really the data, just the beginning. */ 2068 /* 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,
2051 /* Use xfree, not XFree, because x_get_window_property 2072 /* Use xfree, not XFree, because x_get_window_property
2052 calls xmalloc itself. */ 2073 calls xmalloc itself. */
2053 xfree (data); 2074 xfree (data);
2075
2076 /* In case quitting happens below. */
2077 data = NULL;
2054 unblock_input (); 2078 unblock_input ();
2055 2079
2056 /* Clear bytes again. Previously, receive_incremental_selection 2080 /* Clear bytes again. Previously, receive_incremental_selection
@@ -2077,10 +2101,8 @@ x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo,
2077 val = selection_data_to_lisp_data (dpyinfo, data, bytes, 2101 val = selection_data_to_lisp_data (dpyinfo, data, bytes,
2078 actual_type, actual_format); 2102 actual_type, actual_format);
2079 2103
2080 /* Use xfree, not XFree, because x_get_window_property 2104 /* This will also free `data'. */
2081 calls xmalloc itself. */ 2105 return unbind_to (count, val);
2082 xfree (data);
2083 return val;
2084} 2106}
2085 2107
2086/* These functions convert from the selection data read from the server into 2108/* These functions convert from the selection data read from the server into