changeset 4830:410ea3e253b9

Revamp xalloc_oversized so that its count arg need not fit into size_t. Fix up group-member, quotearg accordingly.
author Paul Eggert <eggert@cs.ucla.edu>
date Thu, 30 Oct 2003 06:33:39 +0000
parents 2fa22df65c21
children ee1500bc3777
files ChangeLog lib/ChangeLog lib/group-member.c lib/quotearg.c lib/xalloc.h m4/ChangeLog m4/xalloc.m4 modules/group-member
diffstat 8 files changed, 45 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -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
--- a/lib/group-member.c
+++ b/lib/group-member.c
@@ -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 @@
 #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 */
--- 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)
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -20,7 +20,6 @@
 #ifndef XALLOC_H_
 # define XALLOC_H_
 
-# include <stdbool.h>
 # include <stddef.h>
 
 # 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.  */
--- a/m4/ChangeLog
+++ b/m4/ChangeLog
@@ -1,3 +1,7 @@
+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
--- 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
 ])
--- a/modules/group-member
+++ b/modules/group-member
@@ -8,6 +8,7 @@
 
 Depends-on:
 xalloc
+stdbool
 
 configure.ac:
 jm_FUNC_GROUP_MEMBER