Mercurial > hg > octave-nkf > gnulib-hg
changeset 4783:d1dc5d9bf1ba
Revamp xalloc interface so that it can check for address arithmetic overflow.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 13 Oct 2003 06:07:10 +0000 |
parents | bb7b44d87b4f |
children | 1399c70d0a09 |
files | ChangeLog lib/ChangeLog lib/xalloc.h lib/xmalloc.c lib/xstrdup.c m4/ChangeLog m4/xalloc.m4 modules/xalloc |
diffstat | 8 files changed, 107 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-10-12 Paul Eggert <eggert@twinsun.com> + + * modules/xalloc: Do not depend on 'exit'. Depend on 'stdbool'. + Change maintainer from Bruno Haible to 'all'. + 2003-10-10 Simon Josefsson <jas@extundo.com> * modules/argp (Depends-on): Add restrict and strcase.
--- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,18 @@ +2003-10-12 Paul Eggert <eggert@twinsun.com> + + * lib/xalloc.h (xnmalloc, xzalloc, xnrealloc, xclone): New decls. + (XMALLOC, XCALLOC, XREALLOC, XFREE, CCLONE, CLONE): Deprecate, + and define in terms of the other primitives. + * lib/xmalloc.c: Include stdbool.h; do not include exit.h. + (SIZE_MAX): Define if not already defined. + (array_size_overflow): New function. + (xalloc_die): Abort instead of exiting if 'error' returns. + (xnmalloc, xnrealloc, xzalloc, xclone): New functions. + (xmalloc, xrealloc): Use them. + (xcalloc): Check for address arithmetic overflow. + * lib/xstrdup.c (xstrdup): Use xclone, since memcpy should be + a bit faster than strcpy. + 2003-10-08 Paul Eggert <eggert@twinsun.com> Merge getpass from libc, plus a few fixes.
--- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -48,31 +48,23 @@ memory allocation failure. */ extern void xalloc_die (void) ATTRIBUTE_NORETURN; -void *xmalloc (size_t n); +void *xmalloc (size_t s); +void *xnmalloc (size_t n, size_t s); +void *xzalloc (size_t s); void *xcalloc (size_t n, size_t s); -void *xrealloc (void *p, size_t n); +void *xrealloc (void *p, size_t s); +void *xnrealloc (void *p, size_t n, size_t s); +void *xclone (void const *p, size_t s); char *xstrdup (const char *str); -# define XMALLOC(Type, N_items) xmalloc (sizeof (Type) * (N_items)) -# define XCALLOC(Type, N_items) xcalloc (sizeof (Type), N_items) -# define XREALLOC(Ptr, Type, N_items) xrealloc (Ptr, sizeof (Type) * (N_items)) - -/* Declare and alloc memory for VAR of type TYPE. */ -# define NEW(Type, Var) Type *(Var) = XMALLOC (Type, 1) - -/* Free VAR only if non NULL. */ -# define XFREE(Var) \ - do { \ - if (Var) \ - free (Var); \ - } while (0) - -/* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */ -# define CCLONE(Src, Num) \ - (memcpy (xmalloc (sizeof *(Src) * (Num)), Src, sizeof *(Src) * (Num))) - -/* Return a malloc'ed copy of SRC. */ -# define CLONE(Src) CCLONE (Src, 1) - +/* These macros are deprecated; they will go away soon, and are retained + temporarily only to ease conversion to the functions described above. */ +# define CCLONE(p, n) xclone (p, (n) * sizeof *(p)) +# define CLONE(p) xclone (p, sizeof *(p)) +# define NEW(type, var) type *var = xmalloc (sizeof (type)) +# define XCALLOC(type, n) xcalloc (n, sizeof (type)) +# define XMALLOC(type, n) xnmalloc (n, sizeof (type)) +# define XREALLOC(p, type, n) xnrealloc (p, n, sizeof (type)) +# define XFREE(p) free (p) #endif /* !XALLOC_H_ */
--- a/lib/xmalloc.c +++ b/lib/xmalloc.c @@ -23,6 +23,7 @@ #include "xalloc.h" +#include <stdbool.h> #include <stdlib.h> #include "gettext.h" @@ -30,10 +31,11 @@ #define N_(msgid) msgid #include "error.h" -#include "exit.h" #include "exitfail.h" -/* The following tests require AC_PREREQ(2.54). */ +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif #ifndef HAVE_MALLOC "you must run the autoconf test for a GNU libc compatible malloc" @@ -46,6 +48,15 @@ /* If non NULL, call this function when memory is exhausted. */ void (*xalloc_fail_func) (void) = 0; +/* Return true if array of N objects, each of size S, cannot exist due + to arithmetic overflow. S must be nonzero. */ + +static inline bool +array_size_overflow (size_t n, size_t s) +{ + return SIZE_MAX / s < n; +} + /* If XALLOC_FAIL_FUNC is NULL, or does return, display this message before exiting when memory is exhausted. Goes through gettext. */ char const xalloc_msg_memory_exhausted[] = N_("memory exhausted"); @@ -58,8 +69,20 @@ error (exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted)); /* The `noreturn' cannot be given to error, since it may return if its first argument is 0. To help compilers understand the - xalloc_die does terminate, call exit. */ - exit (EXIT_FAILURE); + xalloc_die does terminate, call abort. */ + abort (); +} + +/* Allocate an array of N objects, each with S bytes of memory, + dynamically, with error checking. S must be nonzero. */ + +inline void * +xnmalloc (size_t n, size_t s) +{ + void *p; + if (array_size_overflow (n, s) || ! (p = malloc (n * s))) + xalloc_die (); + return p; } /* Allocate N bytes of memory dynamically, with error checking. */ @@ -67,10 +90,16 @@ void * xmalloc (size_t n) { - void *p; + return xnmalloc (n, 1); +} - p = malloc (n); - if (p == 0) +/* Change the size of an allocated block of memory P to an array of N + objects each of S bytes, with error checking. S must be nonzero. */ + +inline void * +xnrealloc (void *p, size_t n, size_t s) +{ + if (array_size_overflow (n, s) || ! (p = realloc (p, n * s))) xalloc_die (); return p; } @@ -81,21 +110,39 @@ void * xrealloc (void *p, size_t n) { - p = realloc (p, n); - if (p == 0) - xalloc_die (); - return p; + return xnrealloc (p, n, 1); } -/* Allocate memory for N elements of S bytes, with error checking. */ +/* Allocate S bytes of zeroed memory dynamically, with error checking. + There's no need for xnzalloc (N, S), since it would be equivalent + to xcalloc (N, S). */ + +void * +xzalloc (size_t s) +{ + return memset (xmalloc (s), 0, s); +} + +/* Allocate zeroed memory for N elements of S bytes, with error + checking. S must be nonzero. */ void * xcalloc (size_t n, size_t s) { void *p; - - p = calloc (n, s); - if (p == 0) + /* Test for overflow, since some calloc implementations don't have + proper overflow checks. */ + if (array_size_overflow (n, s) || ! (p = calloc (n, s))) xalloc_die (); return p; } + +/* Clone an object P of size S, with error checking. There's no need + for xnclone (P, N, S), since xclone (P, N * S) works without any + need for an arithmetic overflow check. */ + +void * +xclone (void const *p, size_t s) +{ + return memcpy (xmalloc (s), p, s); +}
--- a/lib/xstrdup.c +++ b/lib/xstrdup.c @@ -29,5 +29,5 @@ char * xstrdup (const char *string) { - return strcpy (xmalloc (strlen (string) + 1), string); + return xclone (string, strlen (string) + 1); }
--- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2003-10-12 Paul Eggert <eggert@twinsun.com> + + * xalloc.m4 (gl_PREREQ_XMALLOC): Require AC_C_INLINE. + 2003-10-10 Simon Josefsson <jas@extundo.com> * argp.m4: Add AC_C_INLINE.
--- a/m4/xalloc.m4 +++ b/m4/xalloc.m4 @@ -1,4 +1,4 @@ -# xalloc.m4 serial 3 +# xalloc.m4 serial 4 dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General @@ -14,8 +14,10 @@ # Prerequisites of lib/xmalloc.c. AC_DEFUN([gl_PREREQ_XMALLOC], [ + AC_REQUIRE([AC_C_INLINE]) AC_REQUIRE([jm_FUNC_MALLOC]) AC_REQUIRE([jm_FUNC_REALLOC]) + : ]) # Prerequisites of lib/xstrdup.c.