bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gnulib] change xalloc_oversized to a macro; clean up group-member,


From: Paul Eggert
Subject: [Bug-gnulib] change xalloc_oversized to a macro; clean up group-member, quotearg
Date: 29 Oct 2003 22:43:05 -0800
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3

While cleaning up group-member I ran into a situation where using
xalloc_oversized would have been wrong, since its argument could be
wider than size_t and it could have been truncated.  One simple fix
was to rewrite xalloc_oversized so that it accepts any count operand.
I installed the following:

2003-10-29  Paul Eggert  <address@hidden>

        * lib/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.  Do not include <stdbool.h>; no longer needed.
        * lib/quotearg.c (quotearg_n_options): Use it.
        * lib/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.
        * m4/xalloc.m4 (gl_XALLOC): Undo previous change.
        * modules/group-member: Depend on stdbool.

Index: lib/xalloc.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/xalloc.h,v
retrieving revision 1.19
diff -p -u -r1.19 xalloc.h
--- lib/xalloc.h        27 Oct 2003 08:00:26 -0000      1.19
+++ lib/xalloc.h        30 Oct 2003 06:28:33 -0000
@@ -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, 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: lib/quotearg.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/quotearg.c,v
retrieving revision 1.39
diff -p -u -r1.39 quotearg.c
--- lib/quotearg.c      29 Oct 2003 17:33:05 -0000      1.39
+++ lib/quotearg.c      30 Oct 2003 06:28:33 -0000
@@ -539,7 +539,7 @@ quotearg_n_options (int n, char const *a
     {
       unsigned int n1 = n0 + 1;
 
-      if (SIZE_MAX / sizeof *slotvec < n1)
+      if (xalloc_oversized (n1, sizeof *slotvec))
        xalloc_die ();
 
       if (slotvec == &slotvec0)
Index: lib/group-member.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/group-member.c,v
retrieving revision 1.13
diff -p -u -r1.13 group-member.c
--- lib/group-member.c  9 Sep 2003 21:46:50 -0000       1.13
+++ lib/group-member.c  30 Oct 2003 06:28:33 -0000
@@ -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. */
-
-  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);
-    }
+  if (n_group_slots < 0)
+    return false;
+
+  /* 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: m4/xalloc.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/xalloc.m4,v
retrieving revision 1.5
diff -p -u -r1.5 xalloc.m4
--- m4/xalloc.m4        27 Oct 2003 08:11:10 -0000      1.5
+++ m4/xalloc.m4        30 Oct 2003 06:28:33 -0000
@@ -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 r
 
 AC_DEFUN([gl_XALLOC],
 [
-  AC_REQUIRE([AC_C_INLINE])
   gl_PREREQ_XMALLOC
   gl_PREREQ_XSTRDUP
 ])
Index: modules/group-member
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/group-member,v
retrieving revision 1.3
diff -p -u -r1.3 group-member
--- modules/group-member        20 Jan 2003 10:02:37 -0000      1.3
+++ modules/group-member        30 Oct 2003 06:28:33 -0000
@@ -8,6 +8,7 @@ m4/group-member.m4
 
 Depends-on:
 xalloc
+stdbool
 
 configure.ac:
 jm_FUNC_GROUP_MEMBER




reply via email to

[Prev in Thread] Current Thread [Next in Thread]