diff options
| author | Paul Eggert | 2011-07-28 17:30:00 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 17:30:00 -0700 |
| commit | 34db673b3978bd88aea081882a70bdcdf53028a7 (patch) | |
| tree | 45687e0d92ee98047899b1602c345424889da749 /src | |
| parent | ddff315164d62859e0eb87e89de9f785b953a39a (diff) | |
| download | emacs-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/ChangeLog | 9 | ||||
| -rw-r--r-- | src/keyboard.c | 80 | ||||
| -rw-r--r-- | src/keyboard.h | 2 |
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 @@ | |||
| 1 | 2011-07-29 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-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); | |||
| 435 | static int read_avail_input (int); | 435 | static int read_avail_input (int); |
| 436 | static void get_input_pending (int *, int); | 436 | static void get_input_pending (int *, int); |
| 437 | static int readable_events (int); | 437 | static int readable_events (int); |
| 438 | static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *, | 438 | static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *, |
| 439 | Lisp_Object, int *); | 439 | Lisp_Object, int *); |
| 440 | static Lisp_Object read_char_minibuf_menu_prompt (int, int, | 440 | static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t, |
| 441 | Lisp_Object *); | 441 | Lisp_Object *); |
| 442 | static Lisp_Object make_lispy_event (struct input_event *); | 442 | static 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 | ||
| 2269 | Lisp_Object | 2269 | Lisp_Object |
| 2270 | read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event, | 2270 | read_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 | |||
| 7962 | tool_bar_items (Lisp_Object reuse, int *nitems) | 7963 | tool_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 | ||
| 8402 | static Lisp_Object | 8403 | static Lisp_Object |
| 8403 | read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, | 8404 | read_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. */ |
| 8483 | static char *read_char_minibuf_menu_text; | 8484 | static char *read_char_minibuf_menu_text; |
| 8484 | /* Size of that buffer. */ | 8485 | /* Size of that buffer. */ |
| 8485 | static int read_char_minibuf_menu_width; | 8486 | static ptrdiff_t read_char_minibuf_menu_width; |
| 8486 | 8487 | ||
| 8487 | static Lisp_Object | 8488 | static Lisp_Object |
| 8488 | read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) | 8489 | read_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 | ||
| 8749 | static int | 8744 | static int |
| 8750 | follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs, | 8745 | follow_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 | ||
| 441 | extern Lisp_Object parse_modifiers (Lisp_Object); | 441 | extern Lisp_Object parse_modifiers (Lisp_Object); |
| 442 | extern Lisp_Object reorder_modifiers (Lisp_Object); | 442 | extern Lisp_Object reorder_modifiers (Lisp_Object); |
| 443 | extern Lisp_Object read_char (int, int, Lisp_Object *, Lisp_Object, | 443 | extern Lisp_Object read_char (int, ptrdiff_t, Lisp_Object *, Lisp_Object, |
| 444 | int *, EMACS_TIME *); | 444 | int *, EMACS_TIME *); |
| 445 | extern int parse_solitary_modifier (Lisp_Object symbol); | 445 | extern int parse_solitary_modifier (Lisp_Object symbol); |
| 446 | 446 | ||