* keymap.c: Integer overflow fixes.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 29 Jul 2011 00:32:09 +0000 (17:32 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 29 Jul 2011 00:32:09 +0000 (17:32 -0700)
(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
src/keymap.c
src/keymap.h

index e42d536..f1c7f11 100644 (file)
@@ -1,5 +1,10 @@
 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)
index 0169276..c968b14 100644 (file)
@@ -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;
 
index 2c826b6..ec9d4ca 100644 (file)
@@ -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);