aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-07-28 17:30:00 -0700
committerPaul Eggert2011-07-28 17:30:00 -0700
commit34db673b3978bd88aea081882a70bdcdf53028a7 (patch)
tree45687e0d92ee98047899b1602c345424889da749 /src
parentddff315164d62859e0eb87e89de9f785b953a39a (diff)
downloademacs-34db673b3978bd88aea081882a70bdcdf53028a7.tar.gz
emacs-34db673b3978bd88aea081882a70bdcdf53028a7.zip
* keyboard.c: Integer and memory overflow fixes.
(read_char, menu_bar_items, tool_bar_items, read_char_x_menu_prompt) (read_char_minibuf_menu_width, read_char_minibuf_menu_prompt) (follow_key, read_key_sequence): Use ptrdiff_t, not int, to count maps. (read_char_minibuf_menu_prompt): Check for overflow in size calculations. Don't update size until allocation succeeds. Redo calculations to avoid overflow. * keyboard.h: Change prototypes to match the above.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/keyboard.c80
-rw-r--r--src/keyboard.h2
3 files changed, 48 insertions, 43 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 5683578fedb..e42d536e6d3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
12011-07-29 Paul Eggert <eggert@cs.ucla.edu> 12011-07-29 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * keyboard.c: Integer and memory overflow fixes.
4 (read_char, menu_bar_items, tool_bar_items, read_char_x_menu_prompt)
5 (read_char_minibuf_menu_width, read_char_minibuf_menu_prompt)
6 (follow_key, read_key_sequence): Use ptrdiff_t, not int, to count maps.
7 (read_char_minibuf_menu_prompt): Check for overflow in size
8 calculations. Don't update size until allocation succeeds. Redo
9 calculations to avoid overflow.
10 * keyboard.h: Change prototypes to match the above.
11
3 * image.c: Integer and memory overflow fixes. 12 * image.c: Integer and memory overflow fixes.
4 (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these are duplicate 13 (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these are duplicate
5 now that they've been promoted to lisp.h. 14 now that they've been promoted to lisp.h.
diff --git a/src/keyboard.c b/src/keyboard.c
index 30fe0d917c4..622f7ca4482 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -435,9 +435,9 @@ static void (*keyboard_init_hook) (void);
435static int read_avail_input (int); 435static int read_avail_input (int);
436static void get_input_pending (int *, int); 436static void get_input_pending (int *, int);
437static int readable_events (int); 437static int readable_events (int);
438static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *, 438static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
439 Lisp_Object, int *); 439 Lisp_Object, int *);
440static Lisp_Object read_char_minibuf_menu_prompt (int, int, 440static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
441 Lisp_Object *); 441 Lisp_Object *);
442static Lisp_Object make_lispy_event (struct input_event *); 442static Lisp_Object make_lispy_event (struct input_event *);
443#if defined (HAVE_MOUSE) || defined (HAVE_GPM) 443#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
@@ -2267,7 +2267,8 @@ do { if (polling_stopped_here) start_polling (); \
2267 Value is t if we showed a menu and the user rejected it. */ 2267 Value is t if we showed a menu and the user rejected it. */
2268 2268
2269Lisp_Object 2269Lisp_Object
2270read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event, 2270read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
2271 Lisp_Object prev_event,
2271 int *used_mouse_menu, struct timeval *end_time) 2272 int *used_mouse_menu, struct timeval *end_time)
2272{ 2273{
2273 volatile Lisp_Object c; 2274 volatile Lisp_Object c;
@@ -7405,7 +7406,7 @@ menu_bar_items (Lisp_Object old)
7405{ 7406{
7406 /* The number of keymaps we're scanning right now, and the number of 7407 /* The number of keymaps we're scanning right now, and the number of
7407 keymaps we have allocated space for. */ 7408 keymaps we have allocated space for. */
7408 int nmaps; 7409 ptrdiff_t nmaps;
7409 7410
7410 /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1] 7411 /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
7411 in the current keymaps, or nil where it is not a prefix. */ 7412 in the current keymaps, or nil where it is not a prefix. */
@@ -7413,7 +7414,7 @@ menu_bar_items (Lisp_Object old)
7413 7414
7414 Lisp_Object def, tail; 7415 Lisp_Object def, tail;
7415 7416
7416 int mapno; 7417 ptrdiff_t mapno;
7417 Lisp_Object oquit; 7418 Lisp_Object oquit;
7418 7419
7419 /* In order to build the menus, we need to call the keymap 7420 /* In order to build the menus, we need to call the keymap
@@ -7458,7 +7459,7 @@ menu_bar_items (Lisp_Object old)
7458 recognized when the menu-bar (or mode-line) is updated, 7459 recognized when the menu-bar (or mode-line) is updated,
7459 which does not normally happen after every command. */ 7460 which does not normally happen after every command. */
7460 Lisp_Object tem; 7461 Lisp_Object tem;
7461 int nminor; 7462 ptrdiff_t nminor;
7462 nminor = current_minor_maps (NULL, &tmaps); 7463 nminor = current_minor_maps (NULL, &tmaps);
7463 maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); 7464 maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
7464 nmaps = 0; 7465 nmaps = 0;
@@ -7962,7 +7963,7 @@ Lisp_Object
7962tool_bar_items (Lisp_Object reuse, int *nitems) 7963tool_bar_items (Lisp_Object reuse, int *nitems)
7963{ 7964{
7964 Lisp_Object *maps; 7965 Lisp_Object *maps;
7965 int nmaps, i; 7966 ptrdiff_t nmaps, i;
7966 Lisp_Object oquit; 7967 Lisp_Object oquit;
7967 Lisp_Object *tmaps; 7968 Lisp_Object *tmaps;
7968 7969
@@ -8002,7 +8003,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
8002 recognized when the tool-bar (or mode-line) is updated, 8003 recognized when the tool-bar (or mode-line) is updated,
8003 which does not normally happen after every command. */ 8004 which does not normally happen after every command. */
8004 Lisp_Object tem; 8005 Lisp_Object tem;
8005 int nminor; 8006 ptrdiff_t nminor;
8006 nminor = current_minor_maps (NULL, &tmaps); 8007 nminor = current_minor_maps (NULL, &tmaps);
8007 maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); 8008 maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
8008 nmaps = 0; 8009 nmaps = 0;
@@ -8400,10 +8401,10 @@ append_tool_bar_item (void)
8400 and do auto-saving in the inner call of read_char. */ 8401 and do auto-saving in the inner call of read_char. */
8401 8402
8402static Lisp_Object 8403static Lisp_Object
8403read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, 8404read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
8404 int *used_mouse_menu) 8405 Lisp_Object prev_event, int *used_mouse_menu)
8405{ 8406{
8406 int mapno; 8407 ptrdiff_t mapno;
8407 8408
8408 if (used_mouse_menu) 8409 if (used_mouse_menu)
8409 *used_mouse_menu = 0; 8410 *used_mouse_menu = 0;
@@ -8431,7 +8432,7 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
8431 Lisp_Object *realmaps 8432 Lisp_Object *realmaps
8432 = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); 8433 = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
8433 Lisp_Object value; 8434 Lisp_Object value;
8434 int nmaps1 = 0; 8435 ptrdiff_t nmaps1 = 0;
8435 8436
8436 /* Use the maps that are not nil. */ 8437 /* Use the maps that are not nil. */
8437 for (mapno = 0; mapno < nmaps; mapno++) 8438 for (mapno = 0; mapno < nmaps; mapno++)
@@ -8482,17 +8483,18 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
8482 We make this bigger when necessary, and never free it. */ 8483 We make this bigger when necessary, and never free it. */
8483static char *read_char_minibuf_menu_text; 8484static char *read_char_minibuf_menu_text;
8484/* Size of that buffer. */ 8485/* Size of that buffer. */
8485static int read_char_minibuf_menu_width; 8486static ptrdiff_t read_char_minibuf_menu_width;
8486 8487
8487static Lisp_Object 8488static Lisp_Object
8488read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) 8489read_char_minibuf_menu_prompt (int commandflag,
8490 ptrdiff_t nmaps, Lisp_Object *maps)
8489{ 8491{
8490 int mapno; 8492 ptrdiff_t mapno;
8491 register Lisp_Object name; 8493 register Lisp_Object name;
8492 int nlength; 8494 ptrdiff_t nlength;
8493 /* FIXME: Use the minibuffer's frame width. */ 8495 /* FIXME: Use the minibuffer's frame width. */
8494 int width = FRAME_COLS (SELECTED_FRAME ()) - 4; 8496 ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
8495 int idx = -1; 8497 ptrdiff_t idx = -1;
8496 int nobindings = 1; 8498 int nobindings = 1;
8497 Lisp_Object rest, vector; 8499 Lisp_Object rest, vector;
8498 char *menu; 8500 char *menu;
@@ -8517,16 +8519,13 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
8517 8519
8518 /* Make sure we have a big enough buffer for the menu text. */ 8520 /* Make sure we have a big enough buffer for the menu text. */
8519 width = max (width, SBYTES (name)); 8521 width = max (width, SBYTES (name));
8520 if (read_char_minibuf_menu_text == 0) 8522 if (STRING_BYTES_BOUND - 4 < width)
8523 memory_full (SIZE_MAX);
8524 if (width + 4 > read_char_minibuf_menu_width)
8521 { 8525 {
8522 read_char_minibuf_menu_width = width + 4;
8523 read_char_minibuf_menu_text = (char *) xmalloc (width + 4);
8524 }
8525 else if (width + 4 > read_char_minibuf_menu_width)
8526 {
8527 read_char_minibuf_menu_width = width + 4;
8528 read_char_minibuf_menu_text 8526 read_char_minibuf_menu_text
8529 = (char *) xrealloc (read_char_minibuf_menu_text, width + 4); 8527 = (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
8528 read_char_minibuf_menu_width = width + 4;
8530 } 8529 }
8531 menu = read_char_minibuf_menu_text; 8530 menu = read_char_minibuf_menu_text;
8532 8531
@@ -8545,7 +8544,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
8545 while (1) 8544 while (1)
8546 { 8545 {
8547 int notfirst = 0; 8546 int notfirst = 0;
8548 int i = nlength; 8547 ptrdiff_t i = nlength;
8549 Lisp_Object obj; 8548 Lisp_Object obj;
8550 Lisp_Object orig_defn_macro; 8549 Lisp_Object orig_defn_macro;
8551 8550
@@ -8644,7 +8643,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
8644 < width 8643 < width
8645 || !notfirst) 8644 || !notfirst)
8646 { 8645 {
8647 int thiswidth; 8646 ptrdiff_t thiswidth;
8648 8647
8649 /* Punctuate between strings. */ 8648 /* Punctuate between strings. */
8650 if (notfirst) 8649 if (notfirst)
@@ -8660,9 +8659,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
8660 if (! char_matches) 8659 if (! char_matches)
8661 { 8660 {
8662 /* Add as much of string as fits. */ 8661 /* Add as much of string as fits. */
8663 thiswidth = SCHARS (desc); 8662 thiswidth = min (SCHARS (desc), width - i);
8664 if (thiswidth + i > width)
8665 thiswidth = width - i;
8666 memcpy (menu + i, SDATA (desc), thiswidth); 8663 memcpy (menu + i, SDATA (desc), thiswidth);
8667 i += thiswidth; 8664 i += thiswidth;
8668 strcpy (menu + i, " = "); 8665 strcpy (menu + i, " = ");
@@ -8670,9 +8667,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
8670 } 8667 }
8671 8668
8672 /* Add as much of string as fits. */ 8669 /* Add as much of string as fits. */
8673 thiswidth = SCHARS (s); 8670 thiswidth = min (SCHARS (s), width - i);
8674 if (thiswidth + i > width)
8675 thiswidth = width - i;
8676 memcpy (menu + i, SDATA (s), thiswidth); 8671 memcpy (menu + i, SDATA (s), thiswidth);
8677 i += thiswidth; 8672 i += thiswidth;
8678 menu[i] = 0; 8673 menu[i] = 0;
@@ -8747,10 +8742,10 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
8747 NEXT may be the same array as CURRENT. */ 8742 NEXT may be the same array as CURRENT. */
8748 8743
8749static int 8744static int
8750follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs, 8745follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current,
8751 Lisp_Object *next) 8746 Lisp_Object *defs, Lisp_Object *next)
8752{ 8747{
8753 int i, first_binding; 8748 ptrdiff_t i, first_binding;
8754 8749
8755 first_binding = nmaps; 8750 first_binding = nmaps;
8756 for (i = nmaps - 1; i >= 0; i--) 8751 for (i = nmaps - 1; i >= 0; i--)
@@ -8960,8 +8955,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
8960 8955
8961 /* The number of keymaps we're scanning right now, and the number of 8956 /* The number of keymaps we're scanning right now, and the number of
8962 keymaps we have allocated space for. */ 8957 keymaps we have allocated space for. */
8963 int nmaps; 8958 ptrdiff_t nmaps;
8964 int nmaps_allocated = 0; 8959 ptrdiff_t nmaps_allocated = 0;
8965 8960
8966 /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in 8961 /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
8967 the current keymaps. */ 8962 the current keymaps. */
@@ -8985,7 +8980,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
8985 /* The index in submaps[] of the first keymap that has a binding for 8980 /* The index in submaps[] of the first keymap that has a binding for
8986 this key sequence. In other words, the lowest i such that 8981 this key sequence. In other words, the lowest i such that
8987 submaps[i] is non-nil. */ 8982 submaps[i] is non-nil. */
8988 int first_binding; 8983 ptrdiff_t first_binding;
8989 /* Index of the first key that has no binding. 8984 /* Index of the first key that has no binding.
8990 It is useless to try fkey.start larger than that. */ 8985 It is useless to try fkey.start larger than that. */
8991 int first_unbound; 8986 int first_unbound;
@@ -9146,8 +9141,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9146 } 9141 }
9147 else 9142 else
9148 { 9143 {
9149 int nminor; 9144 ptrdiff_t nminor;
9150 int total; 9145 ptrdiff_t total;
9151 Lisp_Object *maps; 9146 Lisp_Object *maps;
9152 9147
9153 nminor = current_minor_maps (0, &maps); 9148 nminor = current_minor_maps (0, &maps);
@@ -9213,7 +9208,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9213 echo_local_start and keys_local_start allow us to throw away 9208 echo_local_start and keys_local_start allow us to throw away
9214 just one key. */ 9209 just one key. */
9215 int echo_local_start IF_LINT (= 0); 9210 int echo_local_start IF_LINT (= 0);
9216 int keys_local_start, local_first_binding; 9211 int keys_local_start;
9212 ptrdiff_t local_first_binding;
9217 9213
9218 eassert (indec.end == t || (indec.end > t && indec.end <= mock_input)); 9214 eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
9219 eassert (indec.start <= indec.end); 9215 eassert (indec.start <= indec.end);
diff --git a/src/keyboard.h b/src/keyboard.h
index 69c804c873d..d4339d0529b 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -440,7 +440,7 @@ struct input_event;
440 440
441extern Lisp_Object parse_modifiers (Lisp_Object); 441extern Lisp_Object parse_modifiers (Lisp_Object);
442extern Lisp_Object reorder_modifiers (Lisp_Object); 442extern Lisp_Object reorder_modifiers (Lisp_Object);
443extern Lisp_Object read_char (int, int, Lisp_Object *, Lisp_Object, 443extern Lisp_Object read_char (int, ptrdiff_t, Lisp_Object *, Lisp_Object,
444 int *, EMACS_TIME *); 444 int *, EMACS_TIME *);
445extern int parse_solitary_modifier (Lisp_Object symbol); 445extern int parse_solitary_modifier (Lisp_Object symbol);
446 446