+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.
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++)
{
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. */
}
/* 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,
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
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)
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
/* 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);
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;
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;
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
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;
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;
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;
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;
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;
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;
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
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;
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;
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;
/* 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 */
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;
break;
}
- command = (char *) xmalloc (length);
+ command = XNMALLOC (length, char);
p = command;
for (argp = argv; ; )
# 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
}
/* Allocate and fill the result string. */
- result = (char *) xmalloc (totalsize + 1);
+ result = XNMALLOC (totalsize + 1, char);
p = result;
for (i = argcount; i > 0; i--)
{
-# 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,
# Prerequisites of lib/xalloc.h.
AC_DEFUN([gl_PREREQ_XALLOC], [
+ AC_REQUIRE([AC_C_INLINE])
:
])