From dbe2216bb632ae0bec0cb2c1b0e38454b9d3a753 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 28 Jul 2011 17:32:09 -0700 Subject: [PATCH] * keymap.c: Integer overflow fixes. (cmm_size, current_minor_maps): Use ptrdiff_t, not int, to count maps. (current_minor_maps): Check for size calculation overflow. * keymap.h: Change prototypes to match the above. --- src/ChangeLog | 5 +++++ src/keymap.c | 15 +++++++++++---- src/keymap.h | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index e42d536e6d..f1c7f11c7f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2011-07-29 Paul Eggert + * keymap.c: Integer overflow fixes. + (cmm_size, current_minor_maps): Use ptrdiff_t, not int, to count maps. + (current_minor_maps): Check for size calculation overflow. + * keymap.h: Change prototypes to match the above. + * 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) diff --git a/src/keymap.c b/src/keymap.c index 0169276bef..c968b14d90 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1403,7 +1403,7 @@ silly_event_symbol_error (Lisp_Object c) some systems, static gets macro-defined to be the empty string. Ickypoo. */ static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL; -static int cmm_size = 0; +static ptrdiff_t cmm_size = 0; /* Store a pointer to an array of the currently active minor modes in *modeptr, a pointer to an array of the keymaps of the currently @@ -1423,10 +1423,10 @@ static int cmm_size = 0; loop. Instead, we'll use realloc/malloc and silently truncate the list, let the key sequence be read, and hope some other piece of code signals the error. */ -int +ptrdiff_t current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr) { - int i = 0; + ptrdiff_t i = 0; int list_number = 0; Lisp_Object alist, assoc, var, val; Lisp_Object emulation_alists; @@ -1469,9 +1469,16 @@ current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr) if (i >= cmm_size) { - int newsize, allocsize; + ptrdiff_t newsize, allocsize; Lisp_Object *newmodes, *newmaps; + /* Check for size calculation overflow. Other code + (e.g., read_key_sequence) adds 3 to the count + later, so subtract 3 from the limit here. */ + if (min (PTRDIFF_MAX, SIZE_MAX) / (2 * sizeof *newmodes) - 3 + < cmm_size) + break; + newsize = cmm_size == 0 ? 30 : cmm_size * 2; allocsize = newsize * sizeof *newmodes; diff --git a/src/keymap.h b/src/keymap.h index 2c826b64e1..ec9d4cadbb 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -38,7 +38,7 @@ extern Lisp_Object get_keymap (Lisp_Object, int, int); EXFUN (Fset_keymap_parent, 2); extern int describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object, const char *, int, int, int, int); -extern int current_minor_maps (Lisp_Object **, Lisp_Object **); +extern ptrdiff_t current_minor_maps (Lisp_Object **, Lisp_Object **); extern void initial_define_key (Lisp_Object, int, const char *); extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); extern void syms_of_keymap (void); -- 2.20.1