aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-08-30 19:27:39 +0800
committerPo Lu2022-08-30 19:28:03 +0800
commit0bf5463f8147ea9143d286d5a9df7c8421a1ac4b (patch)
treed7d01c0aee60bcf6963d25f48ee5fe3e013d2d91 /src
parentdb6e574567350f8cf2eec698ea82e62dcd9d27a6 (diff)
downloademacs-0bf5463f8147ea9143d286d5a9df7c8421a1ac4b.tar.gz
emacs-0bf5463f8147ea9143d286d5a9df7c8421a1ac4b.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/xselect.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/src/xselect.c b/src/xselect.c
index bab0400540e..74d762f3055 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1567,7 +1567,8 @@ receive_incremental_selection (struct x_display_info *dpyinfo,
1567 unsigned char **data_ret, 1567 unsigned char **data_ret,
1568 ptrdiff_t *size_bytes_ret, 1568 ptrdiff_t *size_bytes_ret,
1569 Atom *type_ret, int *format_ret, 1569 Atom *type_ret, int *format_ret,
1570 unsigned long *size_ret) 1570 unsigned long *size_ret,
1571 ptrdiff_t *real_bytes_ret)
1571{ 1572{
1572 ptrdiff_t offset = 0; 1573 ptrdiff_t offset = 0;
1573 struct prop_location *wait_object; 1574 struct prop_location *wait_object;
@@ -1622,7 +1623,8 @@ receive_incremental_selection (struct x_display_info *dpyinfo,
1622 1623
1623 if (tmp_size_bytes == 0) /* we're done */ 1624 if (tmp_size_bytes == 0) /* we're done */
1624 { 1625 {
1625 TRACE0 ("Done reading incrementally"); 1626 TRACE1 ("Done reading incrementally; total bytes: %"pD"d",
1627 *size_bytes_ret);
1626 1628
1627 if (! waiting_for_other_props_on_window (display, window)) 1629 if (! waiting_for_other_props_on_window (display, window))
1628 XSelectInput (display, window, STANDARD_EVENT_SET); 1630 XSelectInput (display, window, STANDARD_EVENT_SET);
@@ -1652,6 +1654,19 @@ receive_incremental_selection (struct x_display_info *dpyinfo,
1652 memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes); 1654 memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
1653 offset += tmp_size_bytes; 1655 offset += tmp_size_bytes;
1654 1656
1657 /* *size_bytes_ret is not really the size of the data inside the
1658 buffer; it is the size of the buffer allocated by xpalloc.
1659
1660 This matters when the cardinal specified in the INCR property
1661 (a _lower bound_ on the size of the selection data) is
1662 smaller than the actual selection contents, which can happen
1663 when programs are streaming selection data from a file
1664 descriptor. In that case, we used to return junk if xpalloc
1665 decided to grow the buffer by more than the provided
1666 increment; to avoid that, store the actual size of the
1667 selection data in *real_bytes_ret. */
1668 *real_bytes_ret += tmp_size_bytes;
1669
1655 /* Use xfree, not XFree, because x_get_window_property 1670 /* Use xfree, not XFree, because x_get_window_property
1656 calls xmalloc itself. */ 1671 calls xmalloc itself. */
1657 xfree (tmp_data); 1672 xfree (tmp_data);
@@ -1674,10 +1689,14 @@ x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo,
1674 int actual_format; 1689 int actual_format;
1675 unsigned long actual_size; 1690 unsigned long actual_size;
1676 unsigned char *data = 0; 1691 unsigned char *data = 0;
1677 ptrdiff_t bytes = 0; 1692 ptrdiff_t bytes = 0, array_bytes;
1678 Lisp_Object val; 1693 Lisp_Object val;
1679 Display *display = dpyinfo->display; 1694 Display *display = dpyinfo->display;
1680 1695
1696 /* array_bytes is only used as an argument to xpalloc. The actual
1697 size of the data inside the buffer is inside bytes. */
1698 array_bytes = 0;
1699
1681 TRACE0 ("Reading selection data"); 1700 TRACE0 ("Reading selection data");
1682 1701
1683 x_get_window_property (display, window, property, &data, &bytes, 1702 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,
1718 calls xmalloc itself. */ 1737 calls xmalloc itself. */
1719 xfree (data); 1738 xfree (data);
1720 unblock_input (); 1739 unblock_input ();
1740
1741 /* Clear bytes again. Previously, receive_incremental_selection
1742 would set this to min_size_bytes, but that is now done to
1743 array_bytes instead. */
1744 bytes = 0;
1721 receive_incremental_selection (dpyinfo, window, property, target_type, 1745 receive_incremental_selection (dpyinfo, window, property, target_type,
1722 min_size_bytes, &data, &bytes, 1746 min_size_bytes, &data, &array_bytes,
1723 &actual_type, &actual_format, 1747 &actual_type, &actual_format,
1724 &actual_size); 1748 &actual_size, &bytes);
1725 } 1749 }
1726 1750
1727 if (!for_multiple) 1751 if (!for_multiple)