>From 1480d4e7caaa85ce7d572f84aec2f6048f014f75 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Thu, 19 Feb 2009 16:06:49 -0800 Subject: [PATCH] Changes suggested by Bruno Haible * rename xalloc_oversized to safe_alloc_oversized to avoid collision with xalloc.h * use safe_alloc_oversized before call to calloc, too * fix indentation to be (hopefully) in accordance with GNU standards * adjust copyright notice for (C) FSF * add a simple unit test --- lib/safe-alloc.c | 32 ++++++++++++----------- lib/safe-alloc.h | 49 +++++++++++++++++++---------------- modules/safe-alloc-tests | 10 +++++++ tests/test-safe-alloc.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 38 deletions(-) create mode 100644 modules/safe-alloc-tests create mode 100644 tests/test-safe-alloc.c diff --git a/lib/safe-alloc.c b/lib/safe-alloc.c index 640eeb7..fca8754 100644 --- a/lib/safe-alloc.c +++ b/lib/safe-alloc.c @@ -1,7 +1,7 @@ /* * safe-alloc.c: safer memory allocation * - * Copyright (C) 2008, 2009 Daniel P. Berrange + * Copyright (C) 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +19,8 @@ * */ +/* Written by Daniel Berrange , 2008 */ + #include #include @@ -39,9 +41,12 @@ However, malloc (SIZE_MAX) fails on all known hosts where sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for exactly-SIZE_MAX allocations on such hosts; this avoids a test and - branch when S is known to be 1. */ -# define xalloc_oversized(n, s) \ - ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) + branch when S is known to be 1. + + This is the same as xalloc_oversized from xalloc.h +*/ +#define safe_alloc_oversized(n, s) \ + ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) /** @@ -66,19 +71,16 @@ safe_alloc_alloc_n (void *ptrptr, size_t size, size_t count, int zeroed) return 0; } - if (zeroed) + if (safe_alloc_oversized (count, size)) { - *(void **) ptrptr = calloc (count, size); + errno = ENOMEM; + return -1; } + + if (zeroed) + *(void **) ptrptr = calloc (count, size); else - { - if (xalloc_oversized (count, size)) - { - errno = ENOMEM; - return -1; - } - *(void **) ptrptr = malloc (count * size); - } + *(void **) ptrptr = malloc (count * size); if (*(void **) ptrptr == NULL) return -1; @@ -109,7 +111,7 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count) *(void **) ptrptr = NULL; return 0; } - if (xalloc_oversized (count, size)) + if (safe_alloc_oversized (count, size)) { errno = ENOMEM; return -1; diff --git a/lib/safe-alloc.h b/lib/safe-alloc.h index 6e42512..1b7847a 100644 --- a/lib/safe-alloc.h +++ b/lib/safe-alloc.h @@ -1,7 +1,7 @@ /* * memory.c: safer memory allocation * - * Copyright (C) 2008, 2009 Daniel P. Berrange + * Copyright (C) 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,19 +19,20 @@ * */ +/* Written by Daniel Berrange , 2008 */ #ifndef SAFE_ALLOC_H_ -#define SAFE_ALLOC_H_ +# define SAFE_ALLOC_H_ -#include +# include -#ifndef ATTRIBUTE_RETURN_CHECK -#if __GNUC_PREREQ (3, 4) -#define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__)) -#else -#define ATTRIBUTE_RETURN_CHECK -#endif -#endif +# ifndef ATTRIBUTE_RETURN_CHECK +# if __GNUC_PREREQ (3, 4) +# define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__)) +# else +# define ATTRIBUTE_RETURN_CHECK +# endif +# endif /* Don't call these directly - use the macros below */ int @@ -52,8 +53,8 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count) * * Return -1 on failure to allocate, zero on success */ -#define ALLOC(ptr) \ - safe_alloc_alloc_n(&(ptr), sizeof(*(ptr)), 1, 1) +# define ALLOC(ptr) \ + safe_alloc_alloc_n (&(ptr), sizeof(*(ptr)), 1, 1) /** * ALLOC_N: @@ -66,8 +67,8 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count) * * Return -1 on failure, 0 on success */ -#define ALLOC_N(ptr, count) \ - safe_alloc_alloc_n(&(ptr), sizeof(*(ptr)), (count), 1) +# define ALLOC_N(ptr, count) \ + safe_alloc_alloc_n (&(ptr), sizeof(*(ptr)), (count), 1) /** * ALLOC_N_UNINITIALIZED: @@ -80,8 +81,8 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count) * * Return -1 on failure to allocate, zero on success */ -#define ALLOC_N_UNINITIALIZED(ptr, count) \ - safe_alloc_alloc_n(&(ptr), sizeof(*(ptr)), (count), 0) +# define ALLOC_N_UNINITIALIZED(ptr, count) \ + safe_alloc_alloc_n (&(ptr), sizeof(*(ptr)), (count), 0) /** * REALLOC_N: @@ -94,8 +95,8 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count) * * Return -1 on failure to reallocate, zero on success */ -#define REALLOC_N(ptr, count) \ - safe_alloc_realloc_n(&(ptr), sizeof(*(ptr)), (count)) +# define REALLOC_N(ptr, count) \ + safe_alloc_realloc_n (&(ptr), sizeof(*(ptr)), (count)) /** * FREE: @@ -104,10 +105,12 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count) * Free the memory stored in 'ptr' and update to point * to NULL. */ -#define FREE(ptr) \ - do { \ - free(ptr); \ - (ptr) = NULL; \ - } while(0) +# define FREE(ptr) \ + do \ + { \ + free(ptr); \ + (ptr) = NULL; \ + } \ + while(0) #endif /* SAFE_ALLOC_H_ */ diff --git a/modules/safe-alloc-tests b/modules/safe-alloc-tests new file mode 100644 index 0000000..dbd9c8f --- /dev/null +++ b/modules/safe-alloc-tests @@ -0,0 +1,10 @@ +Files: +tests/test-safe-alloc.c + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-safe-alloc +check_PROGRAMS += test-safe-alloc diff --git a/tests/test-safe-alloc.c b/tests/test-safe-alloc.c new file mode 100644 index 0000000..420b5e2 --- /dev/null +++ b/tests/test-safe-alloc.c @@ -0,0 +1,63 @@ +/* + * Test the safe-alloc macros + * + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David Lutterkort + */ + +#include + +#include + +#include + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +int main() +{ + struct tst { + int a; + int b; + }; + + struct tst *p = NULL; + int r; + + r = ALLOC(p); + ASSERT(r >= 0); + + ASSERT(p->a == 0 && p->b == 0); + + p->a = p->b = 42; + r = REALLOC_N(p, 5); + + ASSERT(p[0].a == 42 && p[0].b == 42); + + FREE(p); + ASSERT(p == NULL); +} -- 1.6.0.6