2011-07-29 Paul Eggert <eggert@cs.ucla.edu>
+ * 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)
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
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;
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;
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);