Simplify xmalloc expressions. Add overflow check in xmalloc arguments.
authorBruno Haible <bruno@clisp.org>
Mon, 6 Nov 2006 13:03:10 +0000 (13:03 +0000)
committerBruno Haible <bruno@clisp.org>
Mon, 6 Nov 2006 13:03:10 +0000 (13:03 +0000)
17 files changed:
ChangeLog
lib/classpath.c
lib/clean-temp.c
lib/concatpath.c
lib/fatal-signal.c
lib/findprog.c
lib/gl_array_list.c
lib/gl_array_oset.c
lib/gl_avltree_oset.c
lib/gl_carray_list.c
lib/gl_rbtree_oset.c
lib/gl_sublist.c
lib/pagealign_alloc.c
lib/sh-quote.c
lib/xalloc.h
lib/xvasprintf.c
m4/xalloc.m4

index 1745382..dd182cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
 2006-11-03  Bruno Haible  <bruno@clisp.org>
 
+       Simplify xmalloc expressions. Add overflow check in xmalloc arguments.
+       * m4/xalloc.m4 (gl_PREREQ_XALLOC): Require AC_C_INLINE.
+       * lib/xalloc.h (XMALLOC, XNMALLOC, XZALLOC, XCALLOC): New macros.
+       (xnboundedmalloc): New inline function.
+       * lib/classpath.c (new_classpath): Use XNMALLOC instead of xmalloc.
+       * lib/clean-temp.c (create_temp_dir): Use XNMALLOC, XMALLOC instead of
+       xmalloc.
+       * lib/concatpath.c (concatenated_pathname): Use XNMALLOC instead of
+       xmalloc.
+       * lib/fatal-signal.c (at_fatal_signal): Use XNMALLOC instead of xmalloc.
+       * lib/findprog.c (find_in_path): Use XNMALLOC instead of xmalloc.
+       * lib/gl_array_list.c (gl_array_create_empty): Use XMALLOC instead of
+       xmalloc.
+       (gl_array_create): Use XNMALLOC, XMALLOC instead of xmalloc.
+       * lib/gl_array_oset.c (gl_array_create_empty): Use XNMALLOC instead of
+       xmalloc.
+       * lib/gl_avltree_oset.c (gl_tree_add_first, gl_tree_add_before,
+       gl_tree_add_after): Use XMALLOC instead of xmalloc.
+       * lib/gl_carray_list.c (gl_carray_create_empty): Use XMALLOC instead of
+       xmalloc.
+       (gl_carray_create): Use XNMALLOC, XMALLOC instead of xmalloc.
+       * lib/gl_rbtree_oset.c (gl_tree_add_first, gl_tree_add_before,
+       gl_tree_add_after): Use XMALLOC instead of xmalloc.
+       * lib/gl_sublist.c (gl_sublist_create): Use XMALLOC instead of xmalloc.
+       * lib/pagealign_alloc.c (new_memnode): Use XMALLOC instead of xmalloc.
+       * lib/sh-quote.c (shell_quote_argv): Use XNMALLOC instead of xmalloc.
+       * lib/xvasprintf.c (xstrcat): Use XNMALLOC instead of xmalloc.
+
+2006-11-03  Bruno Haible  <bruno@clisp.org>
+
        * lib/c-ctype.h [C++]: Define functions without name mangling.
        * lib/fwriteerror.h [C++]: Likewise.
        * lib/gcd.h [C++]: Likewise.
index b87ceab..4809fc6 100644 (file)
@@ -66,7 +66,7 @@ new_classpath (const char * const *classpaths, unsigned int classpaths_count,
   if (classpaths_count > 0 && old_classpath[0] == '\0')
     length--;
 
-  result = (char *) xmalloc (length + 1);
+  result = XNMALLOC (length + 1, char);
   p = result;
   for (i = 0; i < classpaths_count; i++)
     {
index 97b2600..aa82974 100644 (file)
@@ -273,8 +273,7 @@ create_temp_dir (const char *prefix, const char *parentdir,
          size_t old_allocated = cleanup_list.tempdir_allocated;
          size_t new_allocated = 2 * cleanup_list.tempdir_allocated + 1;
          struct tempdir * volatile *new_array =
-           (struct tempdir * volatile *)
-           xmalloc (new_allocated * sizeof (struct tempdir * volatile));
+           XNMALLOC (new_allocated, struct tempdir * volatile);
 
          if (old_allocated == 0)
            /* First use of this facility.  Register the cleanup handler.  */
@@ -306,7 +305,7 @@ create_temp_dir (const char *prefix, const char *parentdir,
     }
 
   /* Initialize a 'struct tempdir'.  */
-  tmpdir = (struct tempdir *) xmalloc (sizeof (struct tempdir));
+  tmpdir = XMALLOC (struct tempdir);
   tmpdir->dirname = NULL;
   tmpdir->cleanup_verbose = cleanup_verbose;
   tmpdir->subdirs = gl_list_create_empty (GL_LINKEDHASH_LIST,
index d39a1fb..01e47f3 100644 (file)
@@ -42,9 +42,10 @@ concatenated_pathname (const char *directory, const char *filename,
   if (strcmp (directory, ".") == 0)
     {
       /* No need to prepend the directory.  */
-      result = (char *) xmalloc (strlen (filename)
-                                + (suffix != NULL ? strlen (suffix) : 0)
-                                + 1);
+      result = XNMALLOC (strlen (filename)
+                        + (suffix != NULL ? strlen (suffix) : 0)
+                        + 1,
+                        char);
       p = result;
     }
   else
@@ -53,10 +54,11 @@ concatenated_pathname (const char *directory, const char *filename,
       int need_slash =
        (directory_len > FILE_SYSTEM_PREFIX_LEN (directory)
         && !ISSLASH (directory[directory_len - 1]));
-      result = (char *) xmalloc (directory_len + need_slash
-                                + strlen (filename)
-                                + (suffix != NULL ? strlen (suffix) : 0)
-                                + 1);
+      result = XNMALLOC (directory_len + need_slash
+                        + strlen (filename)
+                        + (suffix != NULL ? strlen (suffix) : 0)
+                        + 1,
+                        char);
       memcpy (result, directory, directory_len);
       p = result + directory_len;
       if (need_slash)
index 2b93b60..e9c9d04 100644 (file)
@@ -206,8 +206,7 @@ at_fatal_signal (action_t action)
       size_t old_actions_allocated = actions_allocated;
       size_t new_actions_allocated = 2 * actions_allocated;
       actions_entry_t *new_actions =
-       (actions_entry_t *)
-       xmalloc (new_actions_allocated * sizeof (actions_entry_t));
+       XNMALLOC (new_actions_allocated, actions_entry_t);
       size_t k;
 
       /* Don't use memcpy() here, because memcpy takes non-volatile arguments
index 5476b39..301f11d 100644 (file)
@@ -92,7 +92,7 @@ find_in_path (const char *progname)
              /* Add the "./" prefix for real, that concatenated_pathname()
                 optimized away.  This avoids a second PATH search when the
                 caller uses execlp/execvp.  */
-             progpathname = (char *) xmalloc (2 + strlen (progname) + 1);
+             progpathname = XNMALLOC (2 + strlen (progname) + 1, char);
              progpathname[0] = '.';
              progpathname[1] = '/';
              memcpy (progpathname + 2, progname, strlen (progname) + 1);
index 7623f02..918303d 100644 (file)
@@ -58,8 +58,7 @@ gl_array_create_empty (gl_list_implementation_t implementation,
                       gl_listelement_hashcode_fn hashcode_fn,
                       bool allow_duplicates)
 {
-  struct gl_list_impl *list =
-    (struct gl_list_impl *) xmalloc (sizeof (struct gl_list_impl));
+  struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
 
   list->base.vtable = implementation;
   list->base.equals_fn = equals_fn;
@@ -79,8 +78,7 @@ gl_array_create (gl_list_implementation_t implementation,
                 bool allow_duplicates,
                 size_t count, const void **contents)
 {
-  struct gl_list_impl *list =
-    (struct gl_list_impl *) xmalloc (sizeof (struct gl_list_impl));
+  struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
 
   list->base.vtable = implementation;
   list->base.equals_fn = equals_fn;
@@ -88,8 +86,7 @@ gl_array_create (gl_list_implementation_t implementation,
   list->base.allow_duplicates = allow_duplicates;
   if (count > 0)
     {
-      list->elements =
-       (const void **) xmalloc (count * sizeof (const void *));
+      list->elements = XNMALLOC (count, const void *);
       memcpy (list->elements, contents, count * sizeof (const void *));
     }
   else
index a6fdb06..b7e2be0 100644 (file)
@@ -45,8 +45,7 @@ static gl_oset_t
 gl_array_create_empty (gl_oset_implementation_t implementation,
                       gl_setelement_compar_fn compar_fn)
 {
-  struct gl_oset_impl *set =
-    (struct gl_oset_impl *) xmalloc (sizeof (struct gl_oset_impl));
+  struct gl_oset_impl *set = XMALLOC (struct gl_oset_impl);
 
   set->base.vtable = implementation;
   set->base.compar_fn = compar_fn;
index db02ab8..1e38b98 100644 (file)
@@ -310,8 +310,7 @@ static gl_oset_node_t
 gl_tree_add_first (gl_oset_t set, const void *elt)
 {
   /* Create new node.  */
-  gl_oset_node_t new_node =
-    (struct gl_oset_node_impl *) xmalloc (sizeof (struct gl_oset_node_impl));
+  gl_oset_node_t new_node = XMALLOC (struct gl_oset_node_impl);
 
   new_node->left = NULL;
   new_node->right = NULL;
@@ -348,8 +347,7 @@ static gl_oset_node_t
 gl_tree_add_before (gl_oset_t set, gl_oset_node_t node, const void *elt)
 {
   /* Create new node.  */
-  gl_oset_node_t new_node =
-    (struct gl_oset_node_impl *) xmalloc (sizeof (struct gl_oset_node_impl));
+  gl_oset_node_t new_node = XMALLOC (struct gl_oset_node_impl);
   bool height_inc;
 
   new_node->left = NULL;
@@ -386,8 +384,7 @@ static gl_oset_node_t
 gl_tree_add_after (gl_oset_t set, gl_oset_node_t node, const void *elt)
 {
   /* Create new node.  */
-  gl_oset_node_t new_node =
-    (struct gl_oset_node_impl *) xmalloc (sizeof (struct gl_oset_node_impl));
+  gl_oset_node_t new_node = XMALLOC (struct gl_oset_node_impl);
   bool height_inc;
 
   new_node->left = NULL;
index 755ad6f..7630c2a 100644 (file)
@@ -61,8 +61,7 @@ gl_carray_create_empty (gl_list_implementation_t implementation,
                       gl_listelement_hashcode_fn hashcode_fn,
                       bool allow_duplicates)
 {
-  struct gl_list_impl *list =
-    (struct gl_list_impl *) xmalloc (sizeof (struct gl_list_impl));
+  struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
 
   list->base.vtable = implementation;
   list->base.equals_fn = equals_fn;
@@ -83,8 +82,7 @@ gl_carray_create (gl_list_implementation_t implementation,
                 bool allow_duplicates,
                 size_t count, const void **contents)
 {
-  struct gl_list_impl *list =
-    (struct gl_list_impl *) xmalloc (sizeof (struct gl_list_impl));
+  struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
 
   list->base.vtable = implementation;
   list->base.equals_fn = equals_fn;
@@ -92,8 +90,7 @@ gl_carray_create (gl_list_implementation_t implementation,
   list->base.allow_duplicates = allow_duplicates;
   if (count > 0)
     {
-      list->elements =
-       (const void **) xmalloc (count * sizeof (const void *));
+      list->elements = XNMALLOC (count, const void *);
       memcpy (list->elements, contents, count * sizeof (const void *));
     }
   else
index 78636d6..5e74fc7 100644 (file)
@@ -542,8 +542,7 @@ static gl_oset_node_t
 gl_tree_add_first (gl_oset_t set, const void *elt)
 {
   /* Create new node.  */
-  gl_oset_node_t new_node =
-    (struct gl_oset_node_impl *) xmalloc (sizeof (struct gl_oset_node_impl));
+  gl_oset_node_t new_node = XMALLOC (struct gl_oset_node_impl);
 
   new_node->left = NULL;
   new_node->right = NULL;
@@ -578,8 +577,7 @@ static gl_oset_node_t
 gl_tree_add_before (gl_oset_t set, gl_oset_node_t node, const void *elt)
 {
   /* Create new node.  */
-  gl_oset_node_t new_node =
-    (struct gl_oset_node_impl *) xmalloc (sizeof (struct gl_oset_node_impl));
+  gl_oset_node_t new_node = XMALLOC (struct gl_oset_node_impl);
 
   new_node->left = NULL;
   new_node->right = NULL;
@@ -607,8 +605,7 @@ static gl_oset_node_t
 gl_tree_add_after (gl_oset_t set, gl_oset_node_t node, const void *elt)
 {
   /* Create new node.  */
-  gl_oset_node_t new_node =
-    (struct gl_oset_node_impl *) xmalloc (sizeof (struct gl_oset_node_impl));
+  gl_oset_node_t new_node = XMALLOC (struct gl_oset_node_impl);
 
   new_node->left = NULL;
   new_node->right = NULL;
index e851c88..87eb6e1 100644 (file)
@@ -430,8 +430,7 @@ gl_sublist_create (gl_list_t whole_list, size_t start_index, size_t end_index)
     /* Invalid arguments.  */
     abort ();
   {
-    struct gl_list_impl *list =
-      (struct gl_list_impl *) xmalloc (sizeof (struct gl_list_impl));
+    struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
 
     list->base.vtable = &gl_sublist_list_implementation;
     list->base.equals_fn = whole_list->base.equals_fn; /* actually unused */
index 521bde5..cbbe763 100644 (file)
@@ -81,7 +81,7 @@ static memnode_t *memnode_table = NULL;
 static void
 new_memnode (void *aligned_ptr, info_t info)
 {
-  memnode_t *new_node = (memnode_t *) xmalloc (sizeof (memnode_t));
+  memnode_t *new_node = XMALLOC (memnode_t);
   new_node->aligned_ptr = aligned_ptr;
   new_node->info = info;
   new_node->next = memnode_table;
index eeef088..40fbdfe 100644 (file)
@@ -88,7 +88,7 @@ shell_quote_argv (char **argv)
            break;
        }
 
-      command = (char *) xmalloc (length);
+      command = XNMALLOC (length, char);
 
       p = command;
       for (argp = argv; ; )
index 9c397aa..6881ea6 100644 (file)
@@ -71,12 +71,57 @@ char *xstrdup (char const *str);
 # define xalloc_oversized(n, s) \
     ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
 
-/* Return a pointer to a new buffer of S bytes.  This is like xmalloc,
-   except it returns char *.  */
+/* In the following macros, T must be an elementary or structure/union or
+   typedef'ed type, or a pointer to such a type.  To apply one of the
+   following macros to a function pointer or array type, you need to typedef
+   it first and use the typedef name.  */
+
+/* Allocate an object of type T dynamically, with error checking.  */
+/* extern T *XMALLOC (typename T); */
+#define XMALLOC(T) \
+  ((T *) xmalloc (sizeof (T)))
+
+/* Allocate memory for NMEMB elements of type T, with error checking.  */
+/* extern T *XNMALLOC (size_t nmemb, typename T); */
+#if HAVE_INLINE
+/* xnmalloc performs a division and multiplication by sizeof (T).  Arrange to
+   perform the division at compile-time and the multiplication with a factor
+   known at compile-time.  */
+# define XNMALLOC(N,T) \
+   ((T *) (sizeof (T) == 1 \
+          ? xmalloc (N) \
+          : xnboundedmalloc(N, (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / sizeof (T), sizeof (T))))
+static inline void *
+xnboundedmalloc (size_t n, size_t bound, size_t s)
+{
+  if (n > bound)
+    xalloc_die ();
+  return xmalloc (n * s);
+}
+#else
+# define XNMALLOC(N,T) \
+   ((T *) (sizeof (T) == 1 ? xmalloc (N) : xnmalloc (N, sizeof (T))))
+#endif
+
+/* Allocate an object of type T dynamically, with error checking,
+   and zero it.  */
+/* extern T *XZALLOC (typename T); */
+#define XZALLOC(T) \
+  ((T *) xzalloc (sizeof (T)))
+
+/* Allocate memory for NMEMB elements of type T, with error checking,
+   and zero it.  */
+/* extern T *XCALLOC (size_t nmemb, typename T); */
+#define XCALLOC(N,T) \
+  ((T *) xcalloc (N, sizeof (T)))
+
+/* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
+   except it returns char *.
+   xcharalloc (N) is equivalent to XNMALLOC (N, char).  */
 static inline char *
-xcharalloc (size_t s)
+xcharalloc (size_t n)
 {
-  return (char *) xmalloc (s);
+  return (char *) xmalloc (n);
 }
 
 # ifdef __cplusplus
index 30cea93..b684427 100644 (file)
@@ -64,7 +64,7 @@ xstrcat (size_t argcount, va_list args)
     }
 
   /* Allocate and fill the result string.  */
-  result = (char *) xmalloc (totalsize + 1);
+  result = XNMALLOC (totalsize + 1, char);
   p = result;
   for (i = argcount; i > 0; i--)
     {
index 0bb1e63..1ef6ab6 100644 (file)
@@ -1,4 +1,4 @@
-# xalloc.m4 serial 13
+# xalloc.m4 serial 14
 dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -14,6 +14,7 @@ AC_DEFUN([gl_XALLOC],
 
 # Prerequisites of lib/xalloc.h.
 AC_DEFUN([gl_PREREQ_XALLOC], [
+  AC_REQUIRE([AC_C_INLINE])
   :
 ])