[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 0bf5463f81: Fix junk data being returned with incremental selecti
From: |
Po Lu |
Subject: |
master 0bf5463f81: Fix junk data being returned with incremental selection transfers |
Date: |
Tue, 30 Aug 2022 07:28:13 -0400 (EDT) |
branch: master
commit 0bf5463f8147ea9143d286d5a9df7c8421a1ac4b
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Fix junk data being returned with incremental selection transfers
* src/xselect.c (receive_incremental_selection): New arg
REAL_BYTES_RET. Set it to the actual size instead of using the
size of the array after it was grown by xpalloc.
(x_get_window_property_as_lisp_data): Adjust call to
receive_incremental_selection.
---
src/xselect.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/xselect.c b/src/xselect.c
index bab0400540..74d762f305 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1567,7 +1567,8 @@ receive_incremental_selection (struct x_display_info
*dpyinfo,
unsigned char **data_ret,
ptrdiff_t *size_bytes_ret,
Atom *type_ret, int *format_ret,
- unsigned long *size_ret)
+ unsigned long *size_ret,
+ ptrdiff_t *real_bytes_ret)
{
ptrdiff_t offset = 0;
struct prop_location *wait_object;
@@ -1622,7 +1623,8 @@ receive_incremental_selection (struct x_display_info
*dpyinfo,
if (tmp_size_bytes == 0) /* we're done */
{
- TRACE0 ("Done reading incrementally");
+ TRACE1 ("Done reading incrementally; total bytes: %"pD"d",
+ *size_bytes_ret);
if (! waiting_for_other_props_on_window (display, window))
XSelectInput (display, window, STANDARD_EVENT_SET);
@@ -1652,6 +1654,19 @@ receive_incremental_selection (struct x_display_info
*dpyinfo,
memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
offset += tmp_size_bytes;
+ /* *size_bytes_ret is not really the size of the data inside the
+ buffer; it is the size of the buffer allocated by xpalloc.
+
+ This matters when the cardinal specified in the INCR property
+ (a _lower bound_ on the size of the selection data) is
+ smaller than the actual selection contents, which can happen
+ when programs are streaming selection data from a file
+ descriptor. In that case, we used to return junk if xpalloc
+ decided to grow the buffer by more than the provided
+ increment; to avoid that, store the actual size of the
+ selection data in *real_bytes_ret. */
+ *real_bytes_ret += tmp_size_bytes;
+
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
xfree (tmp_data);
@@ -1674,10 +1689,14 @@ x_get_window_property_as_lisp_data (struct
x_display_info *dpyinfo,
int actual_format;
unsigned long actual_size;
unsigned char *data = 0;
- ptrdiff_t bytes = 0;
+ ptrdiff_t bytes = 0, array_bytes;
Lisp_Object val;
Display *display = dpyinfo->display;
+ /* array_bytes is only used as an argument to xpalloc. The actual
+ size of the data inside the buffer is inside bytes. */
+ array_bytes = 0;
+
TRACE0 ("Reading selection data");
x_get_window_property (display, window, property, &data, &bytes,
@@ -1718,10 +1737,15 @@ x_get_window_property_as_lisp_data (struct
x_display_info *dpyinfo,
calls xmalloc itself. */
xfree (data);
unblock_input ();
+
+ /* Clear bytes again. Previously, receive_incremental_selection
+ would set this to min_size_bytes, but that is now done to
+ array_bytes instead. */
+ bytes = 0;
receive_incremental_selection (dpyinfo, window, property, target_type,
- min_size_bytes, &data, &bytes,
+ min_size_bytes, &data, &array_bytes,
&actual_type, &actual_format,
- &actual_size);
+ &actual_size, &bytes);
}
if (!for_multiple)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 0bf5463f81: Fix junk data being returned with incremental selection transfers,
Po Lu <=