* 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.
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)
{
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. */
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, ':');
} \
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
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)
{
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, ':');