* lisp.h (SAFE_ALLOCA_LISP): Check for integer overflow.
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 8 Jun 2011 19:54:32 +0000 (12:54 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 8 Jun 2011 19:54:32 +0000 (12:54 -0700)
(struct Lisp_Save_Value): Use ptrdiff_t, not int, for 'integer' member.
* alloc.c (make_save_value): Integer argument is now of type
ptrdiff_t, not int.
(mark_object): Use ptrdiff_t, not int.
* lisp.h (pD): New macro.
* print.c (print_object): Use it.

src/ChangeLog
src/alloc.c
src/lisp.h
src/print.c

index 0c3028f..100a7b0 100644 (file)
@@ -1,5 +1,13 @@
 2011-06-08  Paul Eggert  <eggert@cs.ucla.edu>
 
+       * lisp.h (SAFE_ALLOCA_LISP): Check for integer overflow.
+       (struct Lisp_Save_Value): Use ptrdiff_t, not int, for 'integer' member.
+       * alloc.c (make_save_value): Integer argument is now of type
+       ptrdiff_t, not int.
+       (mark_object): Use ptrdiff_t, not int.
+       * lisp.h (pD): New macro.
+       * print.c (print_object): Use it.
+
        * alloc.c: Use EMACS_INT, not int, to count objects.
        (total_conses, total_markers, total_symbols, total_vector_size)
        (total_free_conses, total_free_markers, total_free_symbols)
index 4530e0a..fd2884a 100644 (file)
@@ -3160,7 +3160,7 @@ free_misc (Lisp_Object misc)
    The unwind function can get the C values back using XSAVE_VALUE.  */
 
 Lisp_Object
-make_save_value (void *pointer, int integer)
+make_save_value (void *pointer, ptrdiff_t integer)
 {
   register Lisp_Object val;
   register struct Lisp_Save_Value *p;
@@ -5514,7 +5514,7 @@ mark_object (Lisp_Object arg)
            if (ptr->dogc)
              {
                Lisp_Object *p = (Lisp_Object *) ptr->pointer;
-               int nelt;
+               ptrdiff_t nelt;
                for (nelt = ptr->integer; nelt > 0; nelt--, p++)
                  mark_maybe_object (*p);
              }
index a1bc794..6003dae 100644 (file)
@@ -60,6 +60,21 @@ extern void check_cons_list (void);
 # define EMACS_UINT unsigned EMACS_INT
 #endif
 
+/* Use pD to format ptrdiff_t values, which suffice for indexes into
+   buffers and strings.  Emacs never allocates objects larger than
+   PTRDIFF_MAX bytes, as they cause problems with pointer subtraction.
+   In C99, pD can always be "t"; configure it here for the sake of
+   pre-C99 libraries such as glibc 2.0 and Solaris 8.  */
+#if PTRDIFF_MAX == INT_MAX
+# define pD ""
+#elif PTRDIFF_MAX == LONG_MAX
+# define pD "l"
+#elif PTRDIFF_MAX == LLONG_MAX
+# define pD "ll"
+#else
+# define pD "t"
+#endif
+
 /* Extra internal type checking?  */
 
 #ifdef ENABLE_CHECKING
@@ -1455,7 +1470,7 @@ struct Lisp_Save_Value
        area containing INTEGER potential Lisp_Objects.  */
     unsigned int dogc : 1;
     void *pointer;
-    int integer;
+    ptrdiff_t integer;
   };
 
 
@@ -2786,7 +2801,7 @@ extern int abort_on_gc;
 extern Lisp_Object make_float (double);
 extern void display_malloc_warning (void);
 extern int inhibit_garbage_collection (void);
-extern Lisp_Object make_save_value (void *, int);
+extern Lisp_Object make_save_value (void *, ptrdiff_t);
 extern void free_marker (Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);
 extern void init_alloc_once (void);
@@ -3678,18 +3693,19 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object);
 
 #define SAFE_ALLOCA_LISP(buf, nelt)                      \
   do {                                                   \
-    int size_ = (nelt) * sizeof (Lisp_Object);           \
-    if (size_ < MAX_ALLOCA)                              \
-      buf = (Lisp_Object *) alloca (size_);              \
-    else                                                 \
+    if ((nelt) < MAX_ALLOCA / sizeof (Lisp_Object))      \
+      buf = (Lisp_Object *) alloca ((nelt) * sizeof (Lisp_Object));    \
+    else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)) \
       {                                                          \
        Lisp_Object arg_;                                 \
-       buf = (Lisp_Object *) xmalloc (size_);            \
+       buf = (Lisp_Object *) xmalloc ((nelt) * sizeof (Lisp_Object));  \
        arg_ = make_save_value (buf, nelt);               \
        XSAVE_VALUE (arg_)->dogc = 1;                     \
        sa_must_free = 1;                                 \
        record_unwind_protect (safe_alloca_unwind, arg_); \
       }                                                          \
+    else                                                 \
+      memory_full (SIZE_MAX);                            \
   } while (0)
 
 
index 803e3a1..7a3e1bd 100644 (file)
@@ -2004,7 +2004,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
 
        case Lisp_Misc_Save_Value:
          strout ("#<save_value ", -1, -1, printcharfun);
-         sprintf(buf, "ptr=%p int=%d",
+         sprintf(buf, "ptr=%p int=%"pD,
                  XSAVE_VALUE (obj)->pointer,
                  XSAVE_VALUE (obj)->integer);
          strout (buf, -1, -1, printcharfun);