From 7c6d5072278ec9af612e21f0507a009ed37816e1 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 6 Nov 2006 13:03:10 +0000 Subject: [PATCH] Simplify xmalloc expressions. Add overflow check in xmalloc arguments. --- ChangeLog | 30 +++++++++++++++++++++++++++++ lib/classpath.c | 2 +- lib/clean-temp.c | 5 ++--- lib/concatpath.c | 16 +++++++++------- lib/fatal-signal.c | 3 +-- lib/findprog.c | 2 +- lib/gl_array_list.c | 9 +++------ lib/gl_array_oset.c | 3 +-- lib/gl_avltree_oset.c | 9 +++------ lib/gl_carray_list.c | 9 +++------ lib/gl_rbtree_oset.c | 9 +++------ lib/gl_sublist.c | 3 +-- lib/pagealign_alloc.c | 2 +- lib/sh-quote.c | 2 +- lib/xalloc.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++---- lib/xvasprintf.c | 2 +- m4/xalloc.m4 | 3 ++- 17 files changed, 112 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17453822d..dd182cc29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,35 @@ 2006-11-03 Bruno Haible + 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 + * lib/c-ctype.h [C++]: Define functions without name mangling. * lib/fwriteerror.h [C++]: Likewise. * lib/gcd.h [C++]: Likewise. diff --git a/lib/classpath.c b/lib/classpath.c index b87ceab49..4809fc629 100644 --- a/lib/classpath.c +++ b/lib/classpath.c @@ -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++) { diff --git a/lib/clean-temp.c b/lib/clean-temp.c index 97b26008f..aa82974a1 100644 --- a/lib/clean-temp.c +++ b/lib/clean-temp.c @@ -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, diff --git a/lib/concatpath.c b/lib/concatpath.c index d39a1fb15..01e47f393 100644 --- a/lib/concatpath.c +++ b/lib/concatpath.c @@ -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) diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c index 2b93b602a..e9c9d0485 100644 --- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -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 diff --git a/lib/findprog.c b/lib/findprog.c index 5476b39d9..301f11dda 100644 --- a/lib/findprog.c +++ b/lib/findprog.c @@ -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); diff --git a/lib/gl_array_list.c b/lib/gl_array_list.c index 7623f02cc..918303dc2 100644 --- a/lib/gl_array_list.c +++ b/lib/gl_array_list.c @@ -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 diff --git a/lib/gl_array_oset.c b/lib/gl_array_oset.c index a6fdb06e9..b7e2be021 100644 --- a/lib/gl_array_oset.c +++ b/lib/gl_array_oset.c @@ -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; diff --git a/lib/gl_avltree_oset.c b/lib/gl_avltree_oset.c index db02ab895..1e38b984f 100644 --- a/lib/gl_avltree_oset.c +++ b/lib/gl_avltree_oset.c @@ -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; diff --git a/lib/gl_carray_list.c b/lib/gl_carray_list.c index 755ad6f62..7630c2a72 100644 --- a/lib/gl_carray_list.c +++ b/lib/gl_carray_list.c @@ -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 diff --git a/lib/gl_rbtree_oset.c b/lib/gl_rbtree_oset.c index 78636d615..5e74fc727 100644 --- a/lib/gl_rbtree_oset.c +++ b/lib/gl_rbtree_oset.c @@ -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; diff --git a/lib/gl_sublist.c b/lib/gl_sublist.c index e851c882f..87eb6e121 100644 --- a/lib/gl_sublist.c +++ b/lib/gl_sublist.c @@ -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 */ diff --git a/lib/pagealign_alloc.c b/lib/pagealign_alloc.c index 521bde566..cbbe76346 100644 --- a/lib/pagealign_alloc.c +++ b/lib/pagealign_alloc.c @@ -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; diff --git a/lib/sh-quote.c b/lib/sh-quote.c index eeef088fd..40fbdfe9f 100644 --- a/lib/sh-quote.c +++ b/lib/sh-quote.c @@ -88,7 +88,7 @@ shell_quote_argv (char **argv) break; } - command = (char *) xmalloc (length); + command = XNMALLOC (length, char); p = command; for (argp = argv; ; ) diff --git a/lib/xalloc.h b/lib/xalloc.h index 9c397aa75..6881ea678 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -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 diff --git a/lib/xvasprintf.c b/lib/xvasprintf.c index 30cea9364..b68442764 100644 --- a/lib/xvasprintf.c +++ b/lib/xvasprintf.c @@ -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--) { diff --git a/m4/xalloc.m4 b/m4/xalloc.m4 index 0bb1e638f..1ef6ab6dd 100644 --- a/m4/xalloc.m4 +++ b/m4/xalloc.m4 @@ -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]) : ]) -- 2.11.0