changeset 27294:9ada369092a5

Simplify xmalloc expressions. Add overflow check in xmalloc arguments.
author Bruno Haible <bruno@clisp.org>
date Mon, 06 Nov 2006 13:03:10 +0000
parents 6c3b0cb44779
children 544cd72c1c6e
files 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
diffstat 17 files changed, 112 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Nov 06 12:55:16 2006 +0000
+++ b/ChangeLog	Mon Nov 06 13:03:10 2006 +0000
@@ -1,3 +1,33 @@
+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.
--- a/lib/classpath.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/classpath.c	Mon Nov 06 13:03:10 2006 +0000
@@ -66,7 +66,7 @@
   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++)
     {
--- a/lib/clean-temp.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/clean-temp.c	Mon Nov 06 13:03:10 2006 +0000
@@ -273,8 +273,7 @@
 	  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 @@
     }
 
   /* 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,
--- a/lib/concatpath.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/concatpath.c	Mon Nov 06 13:03:10 2006 +0000
@@ -42,9 +42,10 @@
   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 @@
       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)
--- a/lib/fatal-signal.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/fatal-signal.c	Mon Nov 06 13:03:10 2006 +0000
@@ -206,8 +206,7 @@
       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
--- a/lib/findprog.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/findprog.c	Mon Nov 06 13:03:10 2006 +0000
@@ -92,7 +92,7 @@
 	      /* 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);
--- a/lib/gl_array_list.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/gl_array_list.c	Mon Nov 06 13:03:10 2006 +0000
@@ -58,8 +58,7 @@
 		       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 @@
 		 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 @@
   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
--- a/lib/gl_array_oset.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/gl_array_oset.c	Mon Nov 06 13:03:10 2006 +0000
@@ -45,8 +45,7 @@
 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;
--- a/lib/gl_avltree_oset.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/gl_avltree_oset.c	Mon Nov 06 13:03:10 2006 +0000
@@ -310,8 +310,7 @@
 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 @@
 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 @@
 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;
--- a/lib/gl_carray_list.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/gl_carray_list.c	Mon Nov 06 13:03:10 2006 +0000
@@ -61,8 +61,7 @@
 		       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 @@
 		 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 @@
   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
--- a/lib/gl_rbtree_oset.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/gl_rbtree_oset.c	Mon Nov 06 13:03:10 2006 +0000
@@ -542,8 +542,7 @@
 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 @@
 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 @@
 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;
--- a/lib/gl_sublist.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/gl_sublist.c	Mon Nov 06 13:03:10 2006 +0000
@@ -430,8 +430,7 @@
     /* 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 */
--- a/lib/pagealign_alloc.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/pagealign_alloc.c	Mon Nov 06 13:03:10 2006 +0000
@@ -81,7 +81,7 @@
 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;
--- a/lib/sh-quote.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/sh-quote.c	Mon Nov 06 13:03:10 2006 +0000
@@ -88,7 +88,7 @@
 	    break;
 	}
 
-      command = (char *) xmalloc (length);
+      command = XNMALLOC (length, char);
 
       p = command;
       for (argp = argv; ; )
--- a/lib/xalloc.h	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/xalloc.h	Mon Nov 06 13:03:10 2006 +0000
@@ -71,12 +71,57 @@
 # 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
--- a/lib/xvasprintf.c	Mon Nov 06 12:55:16 2006 +0000
+++ b/lib/xvasprintf.c	Mon Nov 06 13:03:10 2006 +0000
@@ -64,7 +64,7 @@
     }
 
   /* Allocate and fill the result string.  */
-  result = (char *) xmalloc (totalsize + 1);
+  result = XNMALLOC (totalsize + 1, char);
   p = result;
   for (i = argcount; i > 0; i--)
     {
--- a/m4/xalloc.m4	Mon Nov 06 12:55:16 2006 +0000
+++ b/m4/xalloc.m4	Mon Nov 06 13:03:10 2006 +0000
@@ -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 @@
 
 # Prerequisites of lib/xalloc.h.
 AC_DEFUN([gl_PREREQ_XALLOC], [
+  AC_REQUIRE([AC_C_INLINE])
   :
 ])