summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--locale/programs/simple-hash.c22
-rw-r--r--localedata/ChangeLog4
-rw-r--r--localedata/charmaps/ISO-8859-164
-rw-r--r--nis/nss_compat/compat-grp.c4
-rw-r--r--nis/nss_compat/compat-pwd.c7
-rw-r--r--nis/nss_nis/nis-grp.c2
-rw-r--r--nis/nss_nis/nis-publickey.c17
-rw-r--r--nis/nss_nis/nis-pwd.c2
-rw-r--r--nis/nss_nisplus/nisplus-grp.c2
-rw-r--r--nis/nss_nisplus/nisplus-parser.c6
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c16
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c2
-rw-r--r--nscd/grpcache.c12
-rw-r--r--nscd/pwdcache.c12
-rw-r--r--nss/getent.c20
-rw-r--r--sysdeps/posix/tempname.c17
16 files changed, 104 insertions, 45 deletions
diff --git a/locale/programs/simple-hash.c b/locale/programs/simple-hash.c
index 35e32ca51e..9056fa0447 100644
--- a/locale/programs/simple-hash.c
+++ b/locale/programs/simple-hash.c
@@ -1,5 +1,5 @@
 /* Implement simple hashing table with string based keys.
-   Copyright (C) 1994, 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1994-1997, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, October 1994.
 
@@ -163,9 +163,11 @@ insert_entry_2 (htab, key, keylen, hval, idx, data)
     }
 
   ++htab->filled;
-  if (100 * htab->filled > 90 * htab->size)
+  if (100 * htab->filled > 75 * htab->size)
     {
-      /* Table is filled more than 90%.  Resize the table.  */
+      /* Table is filled more than 75%.  Resize the table.
+	 Experiments have shown that for best performance, this threshold
+	 must lie between 40% and 85%.  */
       unsigned long int old_size = htab->size;
 
       htab->size = next_prime (htab->size * 2);
@@ -346,22 +348,18 @@ compute_hashval (key, keylen)
      size_t keylen;
 {
   size_t cnt;
-  unsigned long int hval, g;
+  unsigned long int hval;
 
   /* Compute the hash value for the given string.  The algorithm
-     is taken from [Aho,Sethi,Ullman].  */
+     is taken from [Aho,Sethi,Ullman], modified to reduce the number of
+     collisions for short strings with very varied bit patterns.
+     See http://www.clisp.org/haible/hashfunc.html.  */
   cnt = 0;
   hval = keylen;
   while (cnt < keylen)
     {
-      hval <<= 4;
+      hval = (hval << 9) | (hval >> (LONGBITS - 9));
       hval += (unsigned long int) *(((char *) key) + cnt++);
-      g = hval & ((unsigned long) 0xf << (LONGBITS - 4));
-      if (g != 0)
-	{
-	  hval ^= g >> (LONGBITS - 8);
-	  hval ^= g;
-	}
     }
   return hval != 0 ? hval : ~((unsigned long) 0);
 }
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index f1de5be671..716baec061 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,7 @@
+2001-11-21  Bruno Haible  <bruno@clisp.org>
+
+	* charmaps/ISO-8859-16: Swap 0xa5 and 0xab entries.
+
 2001-11-15  Børre Gaup  <boerre.gaup@pc.nu>
 
 	* locales/se_NO: New file.
diff --git a/localedata/charmaps/ISO-8859-16 b/localedata/charmaps/ISO-8859-16
index 359a21f9f0..83fdeb7316 100644
--- a/localedata/charmaps/ISO-8859-16
+++ b/localedata/charmaps/ISO-8859-16
@@ -172,13 +172,13 @@ CHARMAP
 <U0105>     /xa2         LATIN SMALL LETTER A WITH OGONEK
 <U0141>     /xa3         LATIN CAPITAL LETTER L WITH STROKE
 <U20AC>     /xa4         EURO SIGN
-<U00AB>     /xa5         LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+<U201E>     /xa5         DOUBLE LOW-9 QUOTATION MARK
 <U0160>     /xa6         LATIN CAPITAL LETTER S WITH CARON
 <U00A7>     /xa7         SECTION SIGN
 <U0161>     /xa8         LATIN SMALL LETTER S WITH CARON
 <U00A9>     /xa9         COPYRIGHT SIGN
 <U0218>     /xaa         LATIN CAPITAL LETTER S WITH COMMA BELOW
-<U201E>     /xab         DOUBLE LOW-9 QUOTATION MARK
+<U00AB>     /xab         LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
 <U0179>     /xac         LATIN CAPITAL LETTER Z WITH ACUTE
 <U00AD>     /xad         SOFT HYPHEN
 <U017A>     /xae         LATIN SMALL LETTER Z WITH ACUTE
diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c
index 961c3b9b4b..cd939eb9e1 100644
--- a/nis/nss_compat/compat-grp.c
+++ b/nis/nss_compat/compat-grp.c
@@ -764,7 +764,7 @@ getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
       nis_result *res;
       char buf[24 + grptablelen];
 
-      sprintf(buf, "[gid=%d],%s", gid, grptable);
+      sprintf(buf, "[gid=%lu],%s", (unsigned long int) gid, grptable);
       res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
       if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
         {
@@ -794,7 +794,7 @@ getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
 	  return NSS_STATUS_NOTFOUND;
 	}
 
-      snprintf (buf, sizeof (buf), "%d", gid);
+      snprintf (buf, sizeof (buf), "%lu", (unsigned long int) gid);
 
       if (yp_match (domain, "group.bygid", buf, strlen (buf),
 		    &outval, &outvallen) != YPERR_SUCCESS)
diff --git a/nis/nss_compat/compat-pwd.c b/nis/nss_compat/compat-pwd.c
index 3579520944..2a55df2908 100644
--- a/nis/nss_compat/compat-pwd.c
+++ b/nis/nss_compat/compat-pwd.c
@@ -1353,8 +1353,9 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
       nis_result *res;
       char buf[1024 + pwdtablelen];
 
-      snprintf(buf, sizeof (buf), "[uid=%d],%s", uid, pwdtable);
-      res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+      snprintf (buf, sizeof (buf), "[uid=%lu],%s", (unsigned long int) uid,
+                pwdtable);
+      res = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
       if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
         {
           enum nss_status status =  niserr2nss (res->status);
@@ -1383,7 +1384,7 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
           return NSS_STATUS_NOTFOUND;
         }
 
-      sprintf (buf, "%d", uid);
+      sprintf (buf, "%lu", (unsigned long int) uid);
       if (yp_match (domain, "passwd.byuid", buf, strlen (buf),
                     &outval, &outvallen)
           != YPERR_SUCCESS)
diff --git a/nis/nss_nis/nis-grp.c b/nis/nss_nis/nis-grp.c
index 9b7531a68d..e85d68bdf7 100644
--- a/nis/nss_nis/nis-grp.c
+++ b/nis/nss_nis/nis-grp.c
@@ -227,7 +227,7 @@ _nss_nis_getgrgid_r (gid_t gid, struct group *grp,
   if (yp_get_default_domain (&domain))
     return NSS_STATUS_UNAVAIL;
 
-  nlen = sprintf (buf, "%d", gid);
+  nlen = sprintf (buf, "%lu", (unsigned long int) gid);
 
   retval = yperr2nss (yp_match (domain, "group.bygid", buf,
 				nlen, &result, &len));
diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c
index ecdf80f66b..f686054426 100644
--- a/nis/nss_nis/nis-publickey.c
+++ b/nis/nss_nis/nis-publickey.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
 
@@ -143,7 +143,7 @@ static enum nss_status
 parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp,
 		 gid_t *gidlist)
 {
-  char *p;
+  char *p, *ep;
   int gidlen;
 
   if (!s || !isdigit (*s))
@@ -153,7 +153,7 @@ parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp,
     }
 
   /* Fetch the uid */
-  *uidp = (atoi (s));
+  *uidp = strtoul (s, NULL, 10);
 
   if (*uidp == 0)
     {
@@ -175,14 +175,17 @@ parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp,
       return NSS_STATUS_NOTFOUND;
     }
 
-  *gidp = (atoi (p));
+  *gidp = strtoul (p, &ep, 10);
 
   gidlen = 0;
 
-  while ((p = strchr (p, ',')) != NULL)
+  /* After strtoul() ep should point to the first invalid character.
+     This is the marker "," we search for the next value.  */ 
+  while (ep != NULL && *ep == ',')
     {
-      p++;
-      gidlist[gidlen++] = atoi (p);
+      ep++;
+      p = ep;
+      gidlist[gidlen++] = strtoul (p, &ep, 10);
     }
 
   *gidlenp = gidlen;
diff --git a/nis/nss_nis/nis-pwd.c b/nis/nss_nis/nis-pwd.c
index c343d80def..4845fd1c75 100644
--- a/nis/nss_nis/nis-pwd.c
+++ b/nis/nss_nis/nis-pwd.c
@@ -329,7 +329,7 @@ _nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
   if (yp_get_default_domain (&domain))
     return NSS_STATUS_UNAVAIL;
 
-  nlen = sprintf (buf, "%d", uid);
+  nlen = sprintf (buf, "%lu", (unsigned long int) uid);
 
   retval = yperr2nss (yp_match (domain, "passwd.byuid", buf,
 				nlen, &result, &len));
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c
index 7cdf21553b..84bc6746a5 100644
--- a/nis/nss_nisplus/nisplus-grp.c
+++ b/nis/nss_nisplus/nisplus-grp.c
@@ -227,7 +227,7 @@ _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
     nis_result *result;
     char buf[36 + tablename_len];
 
-    sprintf (buf, "[gid=%d],%s", gid, tablename_val);
+    sprintf (buf, "[gid=%lu],%s", (unsigned long int) gid, tablename_val);
 
     result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-parser.c b/nis/nss_nisplus/nisplus-parser.c
index ce121ec22b..f160338cee 100644
--- a/nis/nss_nisplus/nisplus-parser.c
+++ b/nis/nss_nisplus/nisplus-parser.c
@@ -89,7 +89,7 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
   len = strlen (first_unused);
   if (len == 0) /* If we don't have a uid, it's an invalid shadow entry */
     return 0;
-  pw->pw_uid = atoi (first_unused);
+  pw->pw_uid = strtoul (first_unused, NULL, 10);
   room_left -= (len + 1);
   first_unused += (len + 1);
 
@@ -102,7 +102,7 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
   len = strlen (first_unused);
   if (len == 0) /* If we don't have a gid, it's an invalid shadow entry */
     return 0;
-  pw->pw_gid = atoi (first_unused);
+  pw->pw_gid = strtoul (first_unused, NULL, 10);
   room_left -= (len + 1);
   first_unused += (len + 1);
 
@@ -200,7 +200,7 @@ _nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr,
   len = strlen (first_unused);
   if (len == 0) /* We should always have an gid */
     return 0;
-  gr->gr_gid = atoi (first_unused);
+  gr->gr_gid = strtoul (first_unused, NULL, 10);
   room_left -= (strlen (first_unused) + 1);
   first_unused += strlen (first_unused) + 1;
 
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
index 1be6139977..ec1290a683 100644
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (c) 1997, 1999, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
 
@@ -200,6 +200,7 @@ static enum nss_status
 parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist,
 	       int *errnop)
 {
+  char *ep;
   int gidlen;
 
   if (!s || (!isdigit (*s)))
@@ -208,14 +209,17 @@ parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist,
       return NSS_STATUS_NOTFOUND;
     }
 
-  *gidp = atoi (s);
+  *gidp = strtoul (s, &ep, 10);
 
   gidlen = 0;
 
-  while ((s = strchr (s, ',')) != NULL)
+  /* After strtoul() ep should point to the marker ',', which means
+     here starts a new value. */
+  while (ep != NULL && *ep == ',')
     {
-      s++;
-      gidlist[gidlen++] = atoi (s);
+      ep++;
+      s = ep;
+      gidlist[gidlen++] = strtoul (s, &ep, 10);
     }
   *gidlenp = gidlen;
 
@@ -368,7 +372,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
 	    _("netname2user: LOCAL entry for %s in directory %s not unique"),
 	    netname, domain);
   /* Fetch the uid */
-  *uidp = atoi (ENTRY_VAL (res->objects.objects_val, 2));
+  *uidp = strtoul (ENTRY_VAL (res->objects.objects_val, 2), NULL, 10);
 
   if (*uidp == 0)
     {
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
index c387f8e4f8..f7bc8321bd 100644
--- a/nis/nss_nisplus/nisplus-pwd.c
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -235,7 +235,7 @@ _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
     nis_result *result;
     char buf[100 + tablename_len];
 
-    sprintf (buf, "[uid=%d],%s", uid, tablename_val);
+    sprintf (buf, "[uid=%lu],%s", (unsigned long int) uid, tablename_val);
 
     result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index 93a7a0d86d..05ba40ed7c 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -246,8 +246,18 @@ addgrbygid (struct database *db, int fd, request_header *req,
   char *buffer = alloca (buflen);
   struct group resultbuf;
   struct group *grp;
-  gid_t gid = atol (key);
   uid_t oldeuid = 0;
+  char *ep;
+  gid_t gid = strtoul ((char *)key, &ep, 10); 
+  
+  if (*(char*)key == '\0' || *ep != '\0')  /* invalid numeric gid */
+    {
+      if (debug_level > 0)
+        dbg_log (_("Invalid numeric gid \"%s\"!"), (char *)key);
+
+      errno = EINVAL;
+      return;
+    }
 
   if (debug_level > 0)
     dbg_log (_("Haven't found \"%d\" in group cache!"), gid);
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 94d8bd2d55..cae33033e9 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -242,8 +242,18 @@ addpwbyuid (struct database *db, int fd, request_header *req,
   char *buffer = alloca (buflen);
   struct passwd resultbuf;
   struct passwd *pwd;
-  uid_t uid = atol (key);
   uid_t oldeuid = 0;
+  char *ep;
+  uid_t uid = strtoul ((char*) key, &ep, 10); 
+  
+  if (*(char*)key == '\0' || *ep != '\0')  /* invalid numeric uid */
+    {
+      if (debug_level > 0) 
+        dbg_log (_("Invalid numeric uid \"%s\"!"), (char *)key);
+
+      errno = EINVAL;
+      return;
+    }
 
   if (debug_level > 0)
     dbg_log (_("Haven't found \"%d\" in password cache!"), uid);
diff --git a/nss/getent.c b/nss/getent.c
index 1ddd67ad23..7a755f8b1c 100644
--- a/nss/getent.c
+++ b/nss/getent.c
@@ -207,7 +207,15 @@ group_keys (int number, char *key[])
   for (i = 0; i < number; ++i)
     {
       if (isdigit (key[i][0]))
-	grp = getgrgid (atol (key[i]));
+	{
+           char *ep;
+           gid_t arg_gid = strtoul (key[i], &ep, 10); 
+
+           if (*key[i] != '\0' && *ep == '\0')  /* valid numeric uid */
+             grp = getgrgid (arg_gid);
+           else
+             grp = NULL;
+	}
       else
 	grp = getgrnam (key[i]);
 
@@ -404,7 +412,15 @@ passwd_keys (int number, char *key[])
   for (i = 0; i < number; ++i)
     {
       if (isdigit (key[i][0]))
-	pwd = getpwuid (atol (key[i]));
+        {
+	   char *ep;
+	   uid_t arg_uid = strtoul (key[i], &ep, 10); 
+
+           if (*key[i] != '\0' && *ep == '\0')  /* valid numeric uid */
+	     pwd = getpwuid (arg_uid);
+           else
+             pwd = NULL;
+        }
       else
 	pwd = getpwnam (key[i]);
 
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 9c6bc8f5a6..0d4bbc418a 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -231,10 +231,23 @@ __gen_tempname (char *tmpl, int kind)
   char *XXXXXX;
   static uint64_t value;
   uint64_t random_time_bits;
-  int count, fd = -1;
+  unsigned int count;
+  int fd = -1;
   int save_errno = errno;
   struct_stat64 st;
 
+  /* A lower bound on the number of temporary files to attempt to
+     generate.  The maximum total number of temporary file names that
+     can exist for a given template is 62**6.  It should never be
+     necessary to try all these combinations.  Instead if a reasonable
+     number of names is tried (we define reasonable as 62**3) fail to
+     give the system administrator the chance to remove the problems.  */
+  unsigned int attempts_min = 62 * 62 * 62;
+
+  /* The number of times to attempt to generate a temporary file.  To
+     conform to POSIX, this must be no smaller than TMP_MAX.  */
+  unsigned int attempts = attempts_min < TMP_MAX ? TMP_MAX : attempts_min;
+
   len = strlen (tmpl);
   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
     {
@@ -261,7 +274,7 @@ __gen_tempname (char *tmpl, int kind)
 #endif
   value += random_time_bits ^ __getpid ();
 
-  for (count = 0; count < TMP_MAX; value += 7777, ++count)
+  for (count = 0; count < attempts; value += 7777, ++count)
     {
       uint64_t v = value;