Revamp xalloc_oversized so that its count arg need not fit into size_t.
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 30 Oct 2003 06:33:39 +0000 (06:33 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 30 Oct 2003 06:33:39 +0000 (06:33 +0000)
Fix up group-member, quotearg accordingly.

ChangeLog
lib/ChangeLog
lib/group-member.c
lib/quotearg.c
lib/xalloc.h
m4/ChangeLog
m4/xalloc.m4
modules/group-member

index 2c9791c..27332bb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-10-29  Paul Eggert  <eggert@twinsun.com>
+
+       * modules/group-member: Depend on stdbool.
+
 2003-10-20  Bruno Haible  <bruno@clisp.org>
 
        * modules/wait-process: New file.
index 1325ed3..70573a8 100644 (file)
@@ -1,5 +1,15 @@
 2003-10-29  Paul Eggert  <eggert@twinsun.com>
 
+       * xalloc.h (xalloc_oversized): Now a macro, not a function,
+       so that it works even if SIZE_MAX < N.  Do not include <stdbool.h>;
+       no longer needed.
+       * quotearg.c (quotearg_n_options): Use it.
+       * group-member.c: Include <stdbool.h>.
+       (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
index 8823506..9ba49a8 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "group-member.h"
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <stdlib.h>
@@ -40,47 +41,38 @@ struct group_info
 #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 @@ group_member (gid_t gid)
 #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 */
index 83b62fa..c695646 100644 (file)
@@ -539,7 +539,7 @@ quotearg_n_options (int n, char const *arg, size_t argsize,
     {
       unsigned int n1 = n0 + 1;
 
-      if (SIZE_MAX / sizeof *slotvec < n1)
+      if (xalloc_oversized (n1, sizeof *slotvec))
        xalloc_die ();
 
       if (slotvec == &slotvec0)
index 5e81b00..5ccea22 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef XALLOC_H_
 # define XALLOC_H_
 
-# include <stdbool.h>
 # include <stddef.h>
 
 # ifndef __attribute__
@@ -60,15 +59,11 @@ void *x2nrealloc (void *p, size_t *pn, size_t s);
 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.  */
index c5c02d8..b2a8833 100644 (file)
@@ -1,5 +1,9 @@
 2003-10-29  Paul Eggert  <eggert@twinsun.com>
 
+       * xalloc.m4 (gl_XALLOC): Undo previous change.
+
+2003-10-29  Paul Eggert  <eggert@twinsun.com>
+
        * host-os.m4 (UTILS_HOST_OS): Resurrect netbsd*-gnu.  Add comments
        to it, and to knetbsd*-gnu and kfreebsd*-gnu.  Remove the '*' from
        after the 'gnu' in these cases.  This fixes some bugs in the
index 21afc6b..0c14045 100644 (file)
@@ -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 @@ dnl the same distribution terms as the rest of that program.
 
 AC_DEFUN([gl_XALLOC],
 [
-  AC_REQUIRE([AC_C_INLINE])
   gl_PREREQ_XMALLOC
   gl_PREREQ_XSTRDUP
 ])
index 7db8a36..8f8284a 100644 (file)
@@ -8,6 +8,7 @@ m4/group-member.m4
 
 Depends-on:
 xalloc
+stdbool
 
 configure.ac:
 jm_FUNC_GROUP_MEMBER