diff options
| author | Paul Eggert | 2011-06-06 01:29:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-06 01:29:01 -0700 |
| commit | be44ca6cd47bff4cb0dfcfd71aa14f10fdab5434 (patch) | |
| tree | 34110ed6783c1314604f3382e8cd6d0812b939e3 /src/xselect.c | |
| parent | d1f3d2afe1057a99b9dec6d1bd5b57bfee81fdff (diff) | |
| download | emacs-be44ca6cd47bff4cb0dfcfd71aa14f10fdab5434.tar.gz emacs-be44ca6cd47bff4cb0dfcfd71aa14f10fdab5434.zip | |
Check for overflow when converting integer to cons and back.
* charset.c (Fdefine_charset_internal, Fdecode_char):
Use cons_to_unsigned to catch overflow.
(Fencode_char): Use INTEGER_TO_CONS.
* composite.h (LGLYPH_CODE): Use cons_to_unsigned.
(LGLYPH_SET_CODE): Use INTEGER_TO_CONS.
* data.c (long_to_cons, cons_to_long): Remove.
(cons_to_unsigned, cons_to_signed): New functions.
These signal an error for invalid or out-of-range values.
* dired.c (Ffile_attributes): Use INTEGER_TO_CONS.
* fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER.
* font.c (Ffont_variation_glyphs):
* fontset.c (Finternal_char_font): Use INTEGER_TO_CONS.
* lisp.h: Include <intprops.h>.
(INTEGER_TO_CONS, CONS_TO_INTEGER): New macros.
(cons_to_signed, cons_to_unsigned): New decls.
(long_to_cons, cons_to_long): Remove decls.
* undo.c (record_first_change): Use INTEGER_TO_CONS.
(Fprimitive_undo): Use CONS_TO_INTEGER.
* xfns.c (Fx_window_property): Likewise.
* xselect.c: Include <limits.h>.
(x_own_selection, selection_data_to_lisp_data):
Use INTEGER_TO_CONS.
(x_handle_selection_request, x_handle_selection_clear)
(x_get_foreign_selection, Fx_disown_selection_internal)
(Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER.
(lisp_data_to_selection_data): Use cons_to_unsigned.
(x_fill_property_data): Use cons_to_signed.
Report values out of range.
Diffstat (limited to 'src/xselect.c')
| -rw-r--r-- | src/xselect.c | 88 |
1 files changed, 36 insertions, 52 deletions
diff --git a/src/xselect.c b/src/xselect.c index 00d70eee477..5b01fc22a42 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | /* Rewritten by jwz */ | 20 | /* Rewritten by jwz */ |
| 21 | 21 | ||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | #include <limits.h> | ||
| 23 | #include <stdio.h> /* termhooks.h needs this */ | 24 | #include <stdio.h> /* termhooks.h needs this */ |
| 24 | #include <setjmp.h> | 25 | #include <setjmp.h> |
| 25 | 26 | ||
| @@ -335,7 +336,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, | |||
| 335 | Lisp_Object prev_value; | 336 | Lisp_Object prev_value; |
| 336 | 337 | ||
| 337 | selection_data = list4 (selection_name, selection_value, | 338 | selection_data = list4 (selection_name, selection_value, |
| 338 | long_to_cons (timestamp), frame); | 339 | INTEGER_TO_CONS (timestamp), frame); |
| 339 | prev_value = LOCAL_SELECTION (selection_name, dpyinfo); | 340 | prev_value = LOCAL_SELECTION (selection_name, dpyinfo); |
| 340 | 341 | ||
| 341 | dpyinfo->terminal->Vselection_alist | 342 | dpyinfo->terminal->Vselection_alist |
| @@ -419,7 +420,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 419 | || INTEGERP (check) | 420 | || INTEGERP (check) |
| 420 | || NILP (value)) | 421 | || NILP (value)) |
| 421 | return value; | 422 | return value; |
| 422 | /* Check for a value that cons_to_long could handle. */ | 423 | /* Check for a value that CONS_TO_INTEGER could handle. */ |
| 423 | else if (CONSP (check) | 424 | else if (CONSP (check) |
| 424 | && INTEGERP (XCAR (check)) | 425 | && INTEGERP (XCAR (check)) |
| 425 | && (INTEGERP (XCDR (check)) | 426 | && (INTEGERP (XCDR (check)) |
| @@ -782,8 +783,8 @@ x_handle_selection_request (struct input_event *event) | |||
| 782 | if (NILP (local_selection_data)) goto DONE; | 783 | if (NILP (local_selection_data)) goto DONE; |
| 783 | 784 | ||
| 784 | /* Decline requests issued prior to our acquiring the selection. */ | 785 | /* Decline requests issued prior to our acquiring the selection. */ |
| 785 | local_selection_time | 786 | CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), |
| 786 | = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); | 787 | Time, local_selection_time); |
| 787 | if (SELECTION_EVENT_TIME (event) != CurrentTime | 788 | if (SELECTION_EVENT_TIME (event) != CurrentTime |
| 788 | && local_selection_time > SELECTION_EVENT_TIME (event)) | 789 | && local_selection_time > SELECTION_EVENT_TIME (event)) |
| 789 | goto DONE; | 790 | goto DONE; |
| @@ -950,8 +951,8 @@ x_handle_selection_clear (struct input_event *event) | |||
| 950 | /* Well, we already believe that we don't own it, so that's just fine. */ | 951 | /* Well, we already believe that we don't own it, so that's just fine. */ |
| 951 | if (NILP (local_selection_data)) return; | 952 | if (NILP (local_selection_data)) return; |
| 952 | 953 | ||
| 953 | local_selection_time = (Time) | 954 | CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), |
| 954 | cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); | 955 | Time, local_selection_time); |
| 955 | 956 | ||
| 956 | /* We have reasserted the selection since this SelectionClear was | 957 | /* We have reasserted the selection since this SelectionClear was |
| 957 | generated, so we can disregard it. */ | 958 | generated, so we can disregard it. */ |
| @@ -1212,16 +1213,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 1212 | return Qnil; | 1213 | return Qnil; |
| 1213 | 1214 | ||
| 1214 | if (! NILP (time_stamp)) | 1215 | if (! NILP (time_stamp)) |
| 1215 | { | 1216 | CONS_TO_INTEGER (time_stamp, Time, requestor_time); |
| 1216 | if (CONSP (time_stamp)) | ||
| 1217 | requestor_time = (Time) cons_to_long (time_stamp); | ||
| 1218 | else if (INTEGERP (time_stamp)) | ||
| 1219 | requestor_time = (Time) XUINT (time_stamp); | ||
| 1220 | else if (FLOATP (time_stamp)) | ||
| 1221 | requestor_time = (Time) XFLOAT_DATA (time_stamp); | ||
| 1222 | else | ||
| 1223 | error ("TIME_STAMP must be cons or number"); | ||
| 1224 | } | ||
| 1225 | 1217 | ||
| 1226 | BLOCK_INPUT; | 1218 | BLOCK_INPUT; |
| 1227 | TRACE2 ("Get selection %s, type %s", | 1219 | TRACE2 ("Get selection %s, type %s", |
| @@ -1639,7 +1631,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1639 | convert it to a cons of integers, 16 bits in each half. | 1631 | convert it to a cons of integers, 16 bits in each half. |
| 1640 | */ | 1632 | */ |
| 1641 | else if (format == 32 && size == sizeof (int)) | 1633 | else if (format == 32 && size == sizeof (int)) |
| 1642 | return long_to_cons (((unsigned int *) data) [0]); | 1634 | return INTEGER_TO_CONS (((unsigned int *) data) [0]); |
| 1643 | else if (format == 16 && size == sizeof (short)) | 1635 | else if (format == 16 && size == sizeof (short)) |
| 1644 | return make_number ((int) (((unsigned short *) data) [0])); | 1636 | return make_number ((int) (((unsigned short *) data) [0])); |
| 1645 | 1637 | ||
| @@ -1665,7 +1657,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1665 | for (i = 0; i < size / 4; i++) | 1657 | for (i = 0; i < size / 4; i++) |
| 1666 | { | 1658 | { |
| 1667 | unsigned int j = ((unsigned int *) data) [i]; | 1659 | unsigned int j = ((unsigned int *) data) [i]; |
| 1668 | Faset (v, make_number (i), long_to_cons (j)); | 1660 | Faset (v, make_number (i), INTEGER_TO_CONS (j)); |
| 1669 | } | 1661 | } |
| 1670 | return v; | 1662 | return v; |
| 1671 | } | 1663 | } |
| @@ -1742,7 +1734,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1742 | *size_ret = 1; | 1734 | *size_ret = 1; |
| 1743 | *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); | 1735 | *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); |
| 1744 | (*data_ret) [sizeof (long)] = 0; | 1736 | (*data_ret) [sizeof (long)] = 0; |
| 1745 | (*(unsigned long **) data_ret) [0] = cons_to_long (obj); | 1737 | (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); |
| 1746 | if (NILP (type)) type = QINTEGER; | 1738 | if (NILP (type)) type = QINTEGER; |
| 1747 | } | 1739 | } |
| 1748 | else if (VECTORP (obj)) | 1740 | else if (VECTORP (obj)) |
| @@ -1790,11 +1782,11 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1790 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); | 1782 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); |
| 1791 | for (i = 0; i < *size_ret; i++) | 1783 | for (i = 0; i < *size_ret; i++) |
| 1792 | if (*format_ret == 32) | 1784 | if (*format_ret == 32) |
| 1793 | (*((unsigned long **) data_ret)) [i] | 1785 | (*((unsigned long **) data_ret)) [i] = |
| 1794 | = cons_to_long (XVECTOR (obj)->contents [i]); | 1786 | cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); |
| 1795 | else | 1787 | else |
| 1796 | (*((unsigned short **) data_ret)) [i] | 1788 | (*((unsigned short **) data_ret)) [i] = |
| 1797 | = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); | 1789 | cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); |
| 1798 | } | 1790 | } |
| 1799 | } | 1791 | } |
| 1800 | else | 1792 | else |
| @@ -2012,8 +2004,10 @@ frame's display, or the first available X display. */) | |||
| 2012 | selection_atom = symbol_to_x_atom (dpyinfo, selection); | 2004 | selection_atom = symbol_to_x_atom (dpyinfo, selection); |
| 2013 | 2005 | ||
| 2014 | BLOCK_INPUT; | 2006 | BLOCK_INPUT; |
| 2015 | timestamp = (NILP (time_object) ? last_event_timestamp | 2007 | if (NILP (time_object)) |
| 2016 | : cons_to_long (time_object)); | 2008 | timestamp = last_event_timestamp; |
| 2009 | else | ||
| 2010 | CONS_TO_INTEGER (time_object, Time, timestamp); | ||
| 2017 | XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); | 2011 | XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); |
| 2018 | UNBLOCK_INPUT; | 2012 | UNBLOCK_INPUT; |
| 2019 | 2013 | ||
| @@ -2250,12 +2244,8 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2250 | { | 2244 | { |
| 2251 | Lisp_Object o = XCAR (iter); | 2245 | Lisp_Object o = XCAR (iter); |
| 2252 | 2246 | ||
| 2253 | if (INTEGERP (o)) | 2247 | if (INTEGERP (o) || FLOATP (o) || CONSP (o)) |
| 2254 | val = (long) XFASTINT (o); | 2248 | val = cons_to_signed (o, LONG_MIN, LONG_MAX); |
| 2255 | else if (FLOATP (o)) | ||
| 2256 | val = (long) XFLOAT_DATA (o); | ||
| 2257 | else if (CONSP (o)) | ||
| 2258 | val = (long) cons_to_long (o); | ||
| 2259 | else if (STRINGP (o)) | 2249 | else if (STRINGP (o)) |
| 2260 | { | 2250 | { |
| 2261 | BLOCK_INPUT; | 2251 | BLOCK_INPUT; |
| @@ -2266,9 +2256,19 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2266 | error ("Wrong type, must be string, number or cons"); | 2256 | error ("Wrong type, must be string, number or cons"); |
| 2267 | 2257 | ||
| 2268 | if (format == 8) | 2258 | if (format == 8) |
| 2269 | *d08++ = (char) val; | 2259 | { |
| 2260 | if (CHAR_MIN <= val && val <= CHAR_MAX) | ||
| 2261 | *d08++ = val; | ||
| 2262 | else | ||
| 2263 | error ("Out of 'char' range"); | ||
| 2264 | } | ||
| 2270 | else if (format == 16) | 2265 | else if (format == 16) |
| 2271 | *d16++ = (short) val; | 2266 | { |
| 2267 | if (SHRT_MIN <= val && val <= SHRT_MAX) | ||
| 2268 | *d16++ = val; | ||
| 2269 | else | ||
| 2270 | error ("Out of 'short' range"); | ||
| 2271 | } | ||
| 2272 | else | 2272 | else |
| 2273 | *d32++ = val; | 2273 | *d32++ = val; |
| 2274 | } | 2274 | } |
| @@ -2352,14 +2352,7 @@ If the value is 0 or the atom is not known, return the empty string. */) | |||
| 2352 | Atom atom; | 2352 | Atom atom; |
| 2353 | int had_errors; | 2353 | int had_errors; |
| 2354 | 2354 | ||
| 2355 | if (INTEGERP (value)) | 2355 | CONS_TO_INTEGER (value, Atom, atom); |
| 2356 | atom = (Atom) XUINT (value); | ||
| 2357 | else if (FLOATP (value)) | ||
| 2358 | atom = (Atom) XFLOAT_DATA (value); | ||
| 2359 | else if (CONSP (value)) | ||
| 2360 | atom = (Atom) cons_to_long (value); | ||
| 2361 | else | ||
| 2362 | error ("Wrong type, value must be number or cons"); | ||
| 2363 | 2356 | ||
| 2364 | BLOCK_INPUT; | 2357 | BLOCK_INPUT; |
| 2365 | x_catch_errors (dpy); | 2358 | x_catch_errors (dpy); |
| @@ -2549,17 +2542,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, At | |||
| 2549 | else | 2542 | else |
| 2550 | error ("DEST as a string must be one of PointerWindow or InputFocus"); | 2543 | error ("DEST as a string must be one of PointerWindow or InputFocus"); |
| 2551 | } | 2544 | } |
| 2552 | else if (INTEGERP (dest)) | 2545 | else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) |
| 2553 | wdest = (Window) XFASTINT (dest); | 2546 | CONS_TO_INTEGER (dest, Window, wdest); |
| 2554 | else if (FLOATP (dest)) | ||
| 2555 | wdest = (Window) XFLOAT_DATA (dest); | ||
| 2556 | else if (CONSP (dest)) | ||
| 2557 | { | ||
| 2558 | if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) | ||
| 2559 | error ("Both car and cdr for DEST must be numbers"); | ||
| 2560 | else | ||
| 2561 | wdest = (Window) cons_to_long (dest); | ||
| 2562 | } | ||
| 2563 | else | 2547 | else |
| 2564 | error ("DEST must be a frame, nil, string, number or cons"); | 2548 | error ("DEST must be a frame, nil, string, number or cons"); |
| 2565 | 2549 | ||