* macros.c: Integer and buffer overflow fixes.
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 23 Jun 2011 06:31:41 +0000 (23:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 23 Jun 2011 06:31:41 +0000 (23:31 -0700)
* keyboard.h (struct keyboard.kbd_macro_bufsize):
* macros.c (Fstart_kbd_macro, store_kbd_macro_char):
Use ptrdiff_t, not int, for sizes.
Don't increment bufsize until after realloc succeeds.
Check for size-calculation overflow.
(Fstart_kbd_macro): Use EMACS_INT, not int, for XINT result.

src/ChangeLog
src/keyboard.h
src/macros.c

index 1e9cf82..c3eaaa4 100644 (file)
@@ -1,5 +1,13 @@
 2011-06-23  Paul Eggert  <eggert@cs.ucla.edu>
 
+       * macros.c: Integer and buffer overflow fixes.
+       * keyboard.h (struct keyboard.kbd_macro_bufsize):
+       * macros.c (Fstart_kbd_macro, store_kbd_macro_char):
+       Use ptrdiff_t, not int, for sizes.
+       Don't increment bufsize until after realloc succeeds.
+       Check for size-calculation overflow.
+       (Fstart_kbd_macro): Use EMACS_INT, not int, for XINT result.
+
        * lisp.h (DEFVAR_KBOARD): Use offsetof instead of char * finagling.
 
        * lread.c: Integer overflow fixes.
index 20763c3..91008a3 100644 (file)
@@ -123,7 +123,7 @@ struct kboard
     Lisp_Object *kbd_macro_end;
 
     /* Allocated size of kbd_macro_buffer.  */
-    int kbd_macro_bufsize;
+    ptrdiff_t kbd_macro_bufsize;
 
     /* Last anonymous kbd macro defined.  */
     Lisp_Object KBOARD_INTERNAL_FIELD (Vlast_kbd_macro);
index 3523e51..ea33dbf 100644 (file)
@@ -71,10 +71,10 @@ macro before appending to it. */)
     {
       if (current_kboard->kbd_macro_bufsize > 200)
        {
-         current_kboard->kbd_macro_bufsize = 30;
          current_kboard->kbd_macro_buffer
            = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
                                       30 * sizeof (Lisp_Object));
+         current_kboard->kbd_macro_bufsize = 30;
        }
       current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
       current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
@@ -82,7 +82,8 @@ macro before appending to it. */)
     }
   else
     {
-      int i, len;
+      ptrdiff_t i;
+      EMACS_INT len;
       int cvt;
 
       /* Check the type of last-kbd-macro in case Lisp code changed it.  */
@@ -94,10 +95,13 @@ macro before appending to it. */)
         has put another macro there.  */
       if (current_kboard->kbd_macro_bufsize < len + 30)
        {
-         current_kboard->kbd_macro_bufsize = len + 30;
+         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object) - 30
+             < current_kboard->kbd_macro_bufsize)
+           memory_full (SIZE_MAX);
          current_kboard->kbd_macro_buffer
            = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
                                       (len + 30) * sizeof (Lisp_Object));
+         current_kboard->kbd_macro_bufsize = len + 30;
        }
 
       /* Must convert meta modifier when copying string to vector.  */
@@ -191,14 +195,17 @@ store_kbd_macro_char (Lisp_Object c)
     {
       if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize)
        {
-         int ptr_offset, end_offset, nbytes;
+         ptrdiff_t ptr_offset, end_offset, nbytes;
 
          ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
          end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
-         kb->kbd_macro_bufsize *= 2;
-         nbytes = kb->kbd_macro_bufsize * sizeof *kb->kbd_macro_buffer;
+         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2
+             < kb->kbd_macro_bufsize)
+           memory_full (SIZE_MAX);
+         nbytes = kb->kbd_macro_bufsize * 2 * sizeof *kb->kbd_macro_buffer;
          kb->kbd_macro_buffer
            = (Lisp_Object *) xrealloc (kb->kbd_macro_buffer, nbytes);
+         kb->kbd_macro_bufsize *= 2;
          kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset;
          kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset;
        }