]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
pinky,who: fix bug in latest change
authorJim Meyering <meyering@redhat.com>
Sun, 15 Jul 2012 16:18:03 +0000 (18:18 +0200)
committerJim Meyering <meyering@redhat.com>
Sun, 15 Jul 2012 17:11:45 +0000 (19:11 +0200)
* src/system.h (stzncpy): New function.
* src/pinky.c (print_entry): Use stzncpy, not stpncpy.
The latter does not NUL-terminate.  I assumed that strncpy was
the only function with such a horrible API.  Today I learned that
stpncpy also may not NUL-terminate its result.
The bugs were introduced in commit v8.17-48-gf79263d.
* src/who.c (print_user): Likewise.
Thanks to Erik Auerswald for spotting my error.

src/pinky.c
src/system.h
src/who.c

index c01b12427893ab2a0701e3e80898e6cb5e147d50..385949aa83d71ac45ab88860d2425acaddcc028a 100644 (file)
@@ -215,7 +215,7 @@ print_entry (const STRUCT_UTMP *utmp_ent)
      absolute file name in ut_line.  */
   if ( ! IS_ABSOLUTE_FILE_NAME (utmp_ent->ut_line))
     p = stpcpy (p, DEV_DIR_WITH_TRAILING_SLASH);
-  stpncpy (p, utmp_ent->ut_line, sizeof (utmp_ent->ut_line));
+  stzncpy (p, utmp_ent->ut_line, sizeof (utmp_ent->ut_line));
 
   if (stat (line, &stats) == 0)
     {
@@ -235,7 +235,7 @@ print_entry (const STRUCT_UTMP *utmp_ent)
       struct passwd *pw;
       char name[UT_USER_SIZE + 1];
 
-      stpncpy (name, UT_USER (utmp_ent), UT_USER_SIZE);
+      stzncpy (name, UT_USER (utmp_ent), UT_USER_SIZE);
       pw = getpwnam (name);
       if (pw == NULL)
         /* TRANSLATORS: Real name is unknown; at most 19 characters. */
@@ -276,7 +276,7 @@ print_entry (const STRUCT_UTMP *utmp_ent)
       char *display = NULL;
 
       /* Copy the host name into UT_HOST, and ensure it's nul terminated. */
-      stpncpy (ut_host, utmp_ent->ut_host, sizeof (utmp_ent->ut_host));
+      stzncpy (ut_host, utmp_ent->ut_host, sizeof (utmp_ent->ut_host));
 
       /* Look for an X display.  */
       display = strchr (ut_host, ':');
index 5e3b3cbdeb50e70edad75e2808b1889d2c3eab06..6907603e6fd64808fbcec1fd505376c41c86aec5 100644 (file)
@@ -626,6 +626,20 @@ The following directory is part of the cycle:\n  %s\n"), \
     }                                  \
   while (0)
 
+/* Like stpncpy, but do ensure that the result is NUL-terminated,
+   and do not NUL-pad out to LEN.  I.e., when strnlen (src, len) == len,
+   this function writes a NUL byte into dest[len].  Thus, the destination
+   buffer must be at least LEN+1 bytes long.  */
+static inline char *
+stzncpy (char *dest, char const *src, size_t len)
+{
+  char const *src_end = src + len;
+  while (src < src_end && *src)
+    *dest++ = *src++;
+  *dest = 0;
+  return dest;
+}
+
 #ifndef ARRAY_CARDINALITY
 # define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
 #endif
index 3ad80042920ac70cde723a62062875ab15fdbc7e..00a6e37de2abd938033360c09bad04383ce8ab7d 100644 (file)
--- a/src/who.c
+++ b/src/who.c
@@ -350,7 +350,7 @@ print_user (const STRUCT_UTMP *utmp_ent, time_t boottime)
      absolute file name in ut_line.  */
   if ( ! IS_ABSOLUTE_FILE_NAME (utmp_ent->ut_line))
     p = stpcpy (p, DEV_DIR_WITH_TRAILING_SLASH);
-  stpncpy (p, utmp_ent->ut_line, sizeof (utmp_ent->ut_line));
+  stzncpy (p, utmp_ent->ut_line, sizeof (utmp_ent->ut_line));
 
   if (stat (line, &stats) == 0)
     {
@@ -376,7 +376,7 @@ print_user (const STRUCT_UTMP *utmp_ent, time_t boottime)
       char *display = NULL;
 
       /* Copy the host name into UT_HOST, and ensure it's nul terminated. */
-      stpncpy (ut_host, utmp_ent->ut_host, sizeof (utmp_ent->ut_host));
+      stzncpy (ut_host, utmp_ent->ut_host, sizeof (utmp_ent->ut_host));
 
       /* Look for an X display.  */
       display = strchr (ut_host, ':');