diff options
| author | Paul Eggert | 2011-08-05 18:10:24 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-08-05 18:10:24 -0700 |
| commit | 252c5ee166b0b5dd82aa1976ae01db704c146a2b (patch) | |
| tree | a14b37241cad583266f1c35b5a0161001c18c9d0 | |
| parent | 458bfed397af18e460d01b888d1da095b6b95034 (diff) | |
| download | emacs-252c5ee166b0b5dd82aa1976ae01db704c146a2b.tar.gz emacs-252c5ee166b0b5dd82aa1976ae01db704c146a2b.zip | |
Adjust further in response to jan.h.d's comments.
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/xselect.c | 55 |
2 files changed, 35 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 53925dae403..7f90c576fb1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | 2011-08-05 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-08-06 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Integer and memory overflow issues. | 3 | Integer and memory overflow issues. |
| 4 | 4 | ||
| @@ -236,7 +236,8 @@ | |||
| 236 | * xrdb.c (get_environ_db): Don't assume path length fits in int, | 236 | * xrdb.c (get_environ_db): Don't assume path length fits in int, |
| 237 | as sprintf is limited to int lengths. | 237 | as sprintf is limited to int lengths. |
| 238 | 238 | ||
| 239 | * xselect.c (X_LONG_SIZE, X_USHRT_MAX, X_ULONG_MAX): New macros. | 239 | * xselect.c (X_LONG_SIZE, X_SHRT_MAX, X_SHRT_MIN, X_LONG_MAX) |
| 240 | (X_LONG_MIN): New macros. | ||
| 240 | Use them to make the following changes clearer. | 241 | Use them to make the following changes clearer. |
| 241 | (MAX_SELECTION_QUANTUM): Make the other bounds on this value clearer. | 242 | (MAX_SELECTION_QUANTUM): Make the other bounds on this value clearer. |
| 242 | This change doesn't affect the value now, but it may help remind | 243 | This change doesn't affect the value now, but it may help remind |
| @@ -255,7 +256,7 @@ | |||
| 255 | (receive_incremental_selection, x_property_data_to_lisp): | 256 | (receive_incremental_selection, x_property_data_to_lisp): |
| 256 | Redo calculations to avoid overflow. | 257 | Redo calculations to avoid overflow. |
| 257 | (x_reply_selection_request): When sending hint, ceiling it at | 258 | (x_reply_selection_request): When sending hint, ceiling it at |
| 258 | X_ULONG_MAX rather than relying on wraparound overflow to send | 259 | X_LONG_MAX rather than relying on wraparound overflow to send |
| 259 | something. | 260 | something. |
| 260 | (x_get_window_property, receive_incremental_selection) | 261 | (x_get_window_property, receive_incremental_selection) |
| 261 | (lisp_data_to_selection_data, x_property_data_to_lisp): | 262 | (lisp_data_to_selection_data, x_property_data_to_lisp): |
diff --git a/src/xselect.c b/src/xselect.c index 5c2e12c5ef1..f5505beffc6 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -111,9 +111,11 @@ static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; | |||
| 111 | is not necessarily sizeof (long). */ | 111 | is not necessarily sizeof (long). */ |
| 112 | #define X_LONG_SIZE 4 | 112 | #define X_LONG_SIZE 4 |
| 113 | 113 | ||
| 114 | /* Maximum unsigned 'short' and 'long' values suitable for libX11. */ | 114 | /* Extreme 'short' and 'long' values suitable for libX11. */ |
| 115 | #define X_USHRT_MAX 0xffff | 115 | #define X_SHRT_MAX 0x7fff |
| 116 | #define X_ULONG_MAX 0xffffffff | 116 | #define X_SHRT_MIN (-1 - X_SHRT_MAX) |
| 117 | #define X_LONG_MAX 0x7fffffff | ||
| 118 | #define X_LONG_MIN (-1 - X_LONG_MAX) | ||
| 117 | 119 | ||
| 118 | /* If this is a smaller number than the max-request-size of the display, | 120 | /* If this is a smaller number than the max-request-size of the display, |
| 119 | emacs will use INCR selection transfer when the selection is larger | 121 | emacs will use INCR selection transfer when the selection is larger |
| @@ -641,7 +643,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy | |||
| 641 | else | 643 | else |
| 642 | { | 644 | { |
| 643 | /* Send an INCR tag to initiate incremental transfer. */ | 645 | /* Send an INCR tag to initiate incremental transfer. */ |
| 644 | unsigned long value[1]; | 646 | long value[1]; |
| 645 | 647 | ||
| 646 | TRACE2 ("Start sending %"pD"d bytes incrementally (%s)", | 648 | TRACE2 ("Start sending %"pD"d bytes incrementally (%s)", |
| 647 | bytes_remaining, XGetAtomName (display, cs->property)); | 649 | bytes_remaining, XGetAtomName (display, cs->property)); |
| @@ -651,7 +653,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy | |||
| 651 | 653 | ||
| 652 | /* XChangeProperty expects an array of long even if long is | 654 | /* XChangeProperty expects an array of long even if long is |
| 653 | more than 32 bits. */ | 655 | more than 32 bits. */ |
| 654 | value[0] = min (bytes_remaining, X_ULONG_MAX); | 656 | value[0] = min (bytes_remaining, X_LONG_MAX); |
| 655 | XChangeProperty (display, window, cs->property, | 657 | XChangeProperty (display, window, cs->property, |
| 656 | dpyinfo->Xatom_INCR, 32, PropModeReplace, | 658 | dpyinfo->Xatom_INCR, 32, PropModeReplace, |
| 657 | (unsigned char *) value, 1); | 659 | (unsigned char *) value, 1); |
| @@ -1764,13 +1766,13 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1764 | (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj); | 1766 | (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj); |
| 1765 | if (NILP (type)) type = QATOM; | 1767 | if (NILP (type)) type = QATOM; |
| 1766 | } | 1768 | } |
| 1767 | else if (RANGED_INTEGERP (0, obj, X_USHRT_MAX)) | 1769 | else if (RANGED_INTEGERP (X_SHRT_MIN, obj, X_SHRT_MAX)) |
| 1768 | { | 1770 | { |
| 1769 | *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); | 1771 | *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); |
| 1770 | *format_ret = 16; | 1772 | *format_ret = 16; |
| 1771 | *size_ret = 1; | 1773 | *size_ret = 1; |
| 1772 | (*data_ret) [sizeof (short)] = 0; | 1774 | (*data_ret) [sizeof (short)] = 0; |
| 1773 | (*(unsigned short **) data_ret) [0] = XINT (obj); | 1775 | (*(short **) data_ret) [0] = XINT (obj); |
| 1774 | if (NILP (type)) type = QINTEGER; | 1776 | if (NILP (type)) type = QINTEGER; |
| 1775 | } | 1777 | } |
| 1776 | else if (INTEGERP (obj) | 1778 | else if (INTEGERP (obj) |
| @@ -1783,7 +1785,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1783 | *format_ret = 32; | 1785 | *format_ret = 32; |
| 1784 | *size_ret = 1; | 1786 | *size_ret = 1; |
| 1785 | (*data_ret) [sizeof (long)] = 0; | 1787 | (*data_ret) [sizeof (long)] = 0; |
| 1786 | (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, X_ULONG_MAX); | 1788 | (*(long **) data_ret) [0] = cons_to_signed (obj, X_LONG_MIN, X_LONG_MAX); |
| 1787 | if (NILP (type)) type = QINTEGER; | 1789 | if (NILP (type)) type = QINTEGER; |
| 1788 | } | 1790 | } |
| 1789 | else if (VECTORP (obj)) | 1791 | else if (VECTORP (obj)) |
| @@ -1817,25 +1819,30 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1817 | int data_size = sizeof (short); | 1819 | int data_size = sizeof (short); |
| 1818 | if (NILP (type)) type = QINTEGER; | 1820 | if (NILP (type)) type = QINTEGER; |
| 1819 | for (i = 0; i < size; i++) | 1821 | for (i = 0; i < size; i++) |
| 1820 | if (X_USHRT_MAX | 1822 | { |
| 1821 | < cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX)) | 1823 | intmax_t v = cons_to_signed (XVECTOR (obj)->contents[i], |
| 1822 | { | 1824 | X_LONG_MIN, X_LONG_MAX); |
| 1823 | /* Use sizeof (long) even if it is more than 32 bits. | 1825 | if (X_SHRT_MIN <= v && v <= X_SHRT_MAX) |
| 1824 | See comment in x_get_window_property and | 1826 | { |
| 1825 | x_fill_property_data. */ | 1827 | /* Use sizeof (long) even if it is more than 32 bits. |
| 1826 | data_size = sizeof (long); | 1828 | See comment in x_get_window_property and |
| 1827 | format = 32; | 1829 | x_fill_property_data. */ |
| 1828 | } | 1830 | data_size = sizeof (long); |
| 1831 | format = 32; | ||
| 1832 | } | ||
| 1833 | } | ||
| 1829 | *data_ret = xnmalloc (size, data_size); | 1834 | *data_ret = xnmalloc (size, data_size); |
| 1830 | *format_ret = format; | 1835 | *format_ret = format; |
| 1831 | *size_ret = size; | 1836 | *size_ret = size; |
| 1832 | for (i = 0; i < size; i++) | 1837 | for (i = 0; i < size; i++) |
| 1833 | if (format == 32) | 1838 | { |
| 1834 | (*((unsigned long **) data_ret)) [i] = | 1839 | long v = cons_to_signed (XVECTOR (obj)->contents[i], |
| 1835 | cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX); | 1840 | X_LONG_MIN, X_LONG_MAX); |
| 1836 | else | 1841 | if (format == 32) |
| 1837 | (*((unsigned short **) data_ret)) [i] = | 1842 | (*((long **) data_ret)) [i] = v; |
| 1838 | cons_to_unsigned (XVECTOR (obj)->contents[i], X_USHRT_MAX); | 1843 | else |
| 1844 | (*((short **) data_ret)) [i] = v; | ||
| 1845 | } | ||
| 1839 | } | 1846 | } |
| 1840 | } | 1847 | } |
| 1841 | else | 1848 | else |
| @@ -2479,7 +2486,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_disp | |||
| 2479 | unsigned long size = 160/event->format; | 2486 | unsigned long size = 160/event->format; |
| 2480 | int x, y; | 2487 | int x, y; |
| 2481 | unsigned char *data = (unsigned char *) event->data.b; | 2488 | unsigned char *data = (unsigned char *) event->data.b; |
| 2482 | unsigned int idata[5]; | 2489 | int idata[5]; |
| 2483 | ptrdiff_t i; | 2490 | ptrdiff_t i; |
| 2484 | 2491 | ||
| 2485 | for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i) | 2492 | for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i) |