# HG changeset patch # User Paul Eggert # Date 1067495619 0 # Node ID 410ea3e253b93b6b0380be73a3d93d9e302ce545 # Parent 2fa22df65c21a050ff2ad688a7d0f08aa8d3b581 Revamp xalloc_oversized so that its count arg need not fit into size_t. Fix up group-member, quotearg accordingly. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-10-29 Paul Eggert + + * modules/group-member: Depend on stdbool. + 2003-10-20 Bruno Haible * modules/wait-process: New file. diff --git a/lib/ChangeLog b/lib/ChangeLog --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,5 +1,15 @@ 2003-10-29 Paul Eggert + * xalloc.h (xalloc_oversized): Now a macro, not a function, + so that it works even if SIZE_MAX < N. Do not include ; + no longer needed. + * quotearg.c (quotearg_n_options): Use it. + * group-member.c: Include . + (free_group_info): Arg is now const *; don't free arg. + (get_group_info): Now returns bool and accepts struct group_info *, + rather than returning a malloc'ed struct group_info *. + All uses changed. Check for overflow in internal size calculation. + * getusershell.c (readname): Simplify the code by using x2nrealloc rather than xmalloc/xrealloc. * linebuffer.c (initbuffer, readlinebuffer): Simplify the code by diff --git a/lib/group-member.c b/lib/group-member.c --- a/lib/group-member.c +++ b/lib/group-member.c @@ -21,6 +21,7 @@ #include "group-member.h" +#include #include #include #include @@ -40,47 +41,38 @@ #if HAVE_GETGROUPS static void -free_group_info (struct group_info *g) +free_group_info (struct group_info const *g) { free (g->group); - free (g); } -static struct group_info * -get_group_info (void) +static bool +get_group_info (struct group_info *gi) { int n_groups; - int n_group_slots; - struct group_info *gi; + int n_group_slots = getgroups (0, NULL); GETGROUPS_T *group; - /* getgroups () returns the number of elements that it was able to - place into the array. We simply continue to call getgroups () - until the number of elements placed into the array is smaller than - the physical size of the array. */ + if (n_group_slots < 0) + return false; - group = NULL; - n_groups = 0; - n_group_slots = 0; - while (n_groups == n_group_slots) - { - n_group_slots += 64; - group = xrealloc (group, n_group_slots * sizeof (GETGROUPS_T)); - n_groups = getgroups (n_group_slots, group); - } + /* Avoid xnmalloc, as it goes awry when SIZE_MAX < n_group_slots. */ + if (xalloc_oversized (n_group_slots, sizeof *group)) + xalloc_die (); + group = xmalloc (n_group_slots * sizeof *group); + n_groups = getgroups (n_group_slots, group); /* In case of error, the user loses. */ if (n_groups < 0) { free (group); - return NULL; + return false; } - gi = xmalloc (sizeof (*gi)); gi->n_groups = n_groups; gi->group = group; - return gi; + return true; } #endif /* not HAVE_GETGROUPS */ @@ -97,24 +89,23 @@ #else int i; int found; - struct group_info *gi; + struct group_info gi; - gi = get_group_info (); - if (gi == NULL) + if (! get_group_info (&gi)) return 0; /* Search through the list looking for GID. */ found = 0; - for (i = 0; i < gi->n_groups; i++) + for (i = 0; i < gi.n_groups; i++) { - if (gid == gi->group[i]) + if (gid == gi.group[i]) { found = 1; break; } } - free_group_info (gi); + free_group_info (&gi); return found; #endif /* HAVE_GETGROUPS */ diff --git a/lib/quotearg.c b/lib/quotearg.c --- a/lib/quotearg.c +++ b/lib/quotearg.c @@ -539,7 +539,7 @@ { unsigned int n1 = n0 + 1; - if (SIZE_MAX / sizeof *slotvec < n1) + if (xalloc_oversized (n1, sizeof *slotvec)) xalloc_die (); if (slotvec == &slotvec0) diff --git a/lib/xalloc.h b/lib/xalloc.h --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -20,7 +20,6 @@ #ifndef XALLOC_H_ # define XALLOC_H_ -# include # include # ifndef __attribute__ @@ -60,15 +59,11 @@ void *xclone (void const *p, size_t s); char *xstrdup (const char *str); -/* Return true if an array of N objects, each of size S, cannot exist - due to size arithmetic overflow. S must be nonzero. */ - -static inline bool -xalloc_oversized (size_t n, size_t s) -{ - size_t size_max = -1; - return size_max / s < n; -} +/* Return 1 if an array of N objects, each of size S, cannot exist due + to size arithmetic overflow. S must be positive and N must be + nonnegative. This is a macro, not an inline function, so that it + works correctly even when SIZE_MAX < N. */ +#define xalloc_oversized(n, s) ((size_t) -1 / (s) < (n)) /* These macros are deprecated; they will go away soon, and are retained temporarily only to ease conversion to the functions described above. */ diff --git a/m4/ChangeLog b/m4/ChangeLog --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2003-10-29 Paul Eggert + + * xalloc.m4 (gl_XALLOC): Undo previous change. + 2003-10-29 Paul Eggert * host-os.m4 (UTILS_HOST_OS): Resurrect netbsd*-gnu. Add comments diff --git a/m4/xalloc.m4 b/m4/xalloc.m4 --- a/m4/xalloc.m4 +++ b/m4/xalloc.m4 @@ -1,4 +1,4 @@ -# xalloc.m4 serial 5 +# xalloc.m4 serial 6 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 @@ -8,7 +8,6 @@ AC_DEFUN([gl_XALLOC], [ - AC_REQUIRE([AC_C_INLINE]) gl_PREREQ_XMALLOC gl_PREREQ_XSTRDUP ]) diff --git a/modules/group-member b/modules/group-member --- a/modules/group-member +++ b/modules/group-member @@ -8,6 +8,7 @@ Depends-on: xalloc +stdbool configure.ac: jm_FUNC_GROUP_MEMBER