Hi Bruno,

On 2026-02-22T08:13:07+0100, Bruno Haible wrote:
> Hi Alejandro,
> 
> > Now that you've added strnul(3) and use it in some places, you may want
> > to also replace another set of strlen(3) uses by strnul(3):
> 
> These changes look OK. Can you please send them in "git format-patch"
> format, as a mail attachment (not inline in a mail)? That would make it
> easy for me to apply.

Sure; please find it attached (it's the patch 2/2).  I've also attached
patch 1/2, which are some places I had changed to use strnul(3),
although if you didn't patch those before, I guess you decided it's not
suitable there, I don't know.


Cheers,
Alex

-- 
<https://www.alejandro-colomar.es>
From 3f2f41c6699c725c1b499feb94ee37c1e64db8d2 Mon Sep 17 00:00:00 2001
Message-ID: <3f2f41c6699c725c1b499feb94ee37c1e64db8d2.1771768913.git....@kernel.org>
From: Alejandro Colomar <[email protected]>
Date: Thu, 19 Feb 2026 03:01:15 +0100
Subject: [PATCH 1/2] Use strnul(3) where it's suitable

Signed-off-by: Alejandro Colomar <[email protected]>
---
 lib/argz.c               | 2 +-
 lib/cpu-supports.c       | 2 +-
 lib/fnmatch.c            | 2 +-
 lib/glob.c               | 2 +-
 lib/link.c               | 2 +-
 lib/localename-unsafe.c  | 2 +-
 lib/mbspcasecmp.c        | 2 +-
 lib/opendir.c            | 2 +-
 lib/parse-duration.c     | 6 +++---
 lib/relocatable.c        | 6 +++---
 lib/setlocale.c          | 2 +-
 lib/strftime.c           | 2 +-
 lib/striconv.c           | 2 +-
 lib/string.in.h          | 2 ++
 lib/strncat.c            | 2 +-
 lib/term-style-control.c | 6 +++---
 lib/vasnprintf.c         | 2 +-
 lib/vc-mtime.c           | 4 ++--
 18 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/lib/argz.c b/lib/argz.c
index 55303dfb19da..0d36c741d931 100644
--- a/lib/argz.c
+++ b/lib/argz.c
@@ -175,7 +175,7 @@ argz_next (const char *argz, size_t argz_len, const char *entry)
   if (entry)
     {
       if (entry < argz + argz_len)
-        entry = strchr (entry, '\0') + 1;
+        entry = strnul (entry) + 1;
 
       return entry >= argz + argz_len ? NULL : (char *) entry;
     }
diff --git a/lib/cpu-supports.c b/lib/cpu-supports.c
index 9057d151eba6..a1505f8bd690 100644
--- a/lib/cpu-supports.c
+++ b/lib/cpu-supports.c
@@ -66,7 +66,7 @@ hwcap_allowed (char const *glibc_hwcap)
 
   char const *sentinel = strchr (hwcaps, ':');
   if (! sentinel)
-    sentinel = hwcaps + strlen (hwcaps);
+    sentinel = strnul (hwcaps);
   char const *cap = hwcaps;
   while ((cap = strstr (cap, glibc_hwcap)) && cap < sentinel)
     { /* Check it's not a partial match.  */
diff --git a/lib/fnmatch.c b/lib/fnmatch.c
index 1b8be9505657..809908dc6d35 100644
--- a/lib/fnmatch.c
+++ b/lib/fnmatch.c
@@ -378,7 +378,7 @@ fnmatch (const char *pattern, const char *string, int flags)
       return res;
     }
 
-  return internal_fnmatch (pattern, string, string + strlen (string),
+  return internal_fnmatch (pattern, string, strnul (string),
                            flags & FNM_PERIOD, flags, NULL, 0);
 }
 
diff --git a/lib/glob.c b/lib/glob.c
index a5c427c3e7c1..7ccbac84966c 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -736,7 +736,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
                 {
                   unescape = strchr (dirname, '\\');
                   if (unescape)
-                    end_name = strchr (unescape, '\0');
+                    end_name = strnul (unescape);
                 }
               else
                 unescape = memchr (dirname, '\\', end_name - dirname);
diff --git a/lib/link.c b/lib/link.c
index 9053eef28f15..6198929943d8 100644
--- a/lib/link.c
+++ b/lib/link.c
@@ -113,7 +113,7 @@ link (const char *file1, const char *file2)
     return -1;
   {
     struct stat st;
-    char *p = strchr (dir, '\0');
+    char *p = strnul (dir);
     while (dir < p && (*--p != '/' && *p != '\\'));
     *p = '\0';
     if (p != dir && stat (dir, &st) != 0 && errno != EOVERFLOW)
diff --git a/lib/localename-unsafe.c b/lib/localename-unsafe.c
index 12748cba28be..d490fe89bee4 100644
--- a/lib/localename-unsafe.c
+++ b/lib/localename-unsafe.c
@@ -2558,7 +2558,7 @@ enum_locales_fn (LPSTR locale_num_str)
     {
       strcat (locval, "_");
       if (GetLocaleInfo (try_lcid, LOCALE_SENGCOUNTRY,
-                        locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
+                        strnul (locval), LOCALE_NAME_MAX_LENGTH))
        {
          size_t locval_len = strlen (locval);
 
diff --git a/lib/mbspcasecmp.c b/lib/mbspcasecmp.c
index 696cb89fb294..a72a20d4fe91 100644
--- a/lib/mbspcasecmp.c
+++ b/lib/mbspcasecmp.c
@@ -45,7 +45,7 @@ mbspcasecmp (const char *string, const char *prefix)
        mbsncasecmp (string, prefix, mbslen (prefix))
      just with small optimizations.  */
   if (string == prefix)
-    return (char *) (string + strlen (string));
+    return (char *) strnul (string);
 
   const char *iter1 = string;
   const char *iter2 = prefix;
diff --git a/lib/opendir.c b/lib/opendir.c
index 3890206b7912..ea3d2ef1662e 100644
--- a/lib/opendir.c
+++ b/lib/opendir.c
@@ -111,7 +111,7 @@ opendir (const char *dir_name)
   {
     char *p;
 
-    p = dir_name_mask + strlen (dir_name_mask);
+    p = strnul (dir_name_mask);
     if (p > dir_name_mask && !ISSLASH (p[-1]))
       *p++ = '\\';
     *p++ = '*';
diff --git a/lib/parse-duration.c b/lib/parse-duration.c
index 5bea54f4e6ce..5abf6a133193 100644
--- a/lib/parse-duration.c
+++ b/lib/parse-duration.c
@@ -192,7 +192,7 @@ parse_year_month_day (cch_t * pz, cch_t * ps)
   res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH);
 
   pz++; /* over the second '-' */
-  ps = pz + strlen (pz);
+  ps = strnul (pz);
   return parse_scaled_value (res, &pz, ps, SEC_PER_DAY);
 }
 
@@ -292,7 +292,7 @@ parse_hour_minute_second (cch_t * pz, cch_t * ps)
   res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN);
 
   pz++;
-  ps = pz + strlen (pz);
+  ps = strnul (pz);
   return parse_scaled_value (res, &pz, ps, 1);
 }
 
@@ -408,7 +408,7 @@ trim (char * pz)
 
   /* trim trailing white space */
   {
-    char * pe = pz + strlen (pz);
+    char * pe = strnul (pz);
     while ((pe > pz) && isspace ((unsigned char)pe[-1]))
       pe--;
     *pe = NUL;
diff --git a/lib/relocatable.c b/lib/relocatable.c
index 3483d0adc0e3..c4b38ec42aaa 100644
--- a/lib/relocatable.c
+++ b/lib/relocatable.c
@@ -214,7 +214,7 @@ compute_curr_prefix (const char *orig_installprefix,
   char *curr_installdir;
   {
     const char *p_base = curr_pathname + FILE_SYSTEM_PREFIX_LEN (curr_pathname);
-    const char *p = curr_pathname + strlen (curr_pathname);
+    const char *p = strnul (curr_pathname);
     char *q;
 
     while (p > p_base)
@@ -237,8 +237,8 @@ compute_curr_prefix (const char *orig_installprefix,
   /* Compute the current installation prefix by removing the trailing
      rel_installdir from it.  */
   {
-    const char *rp = rel_installdir + strlen (rel_installdir);
-    const char *cp = curr_installdir + strlen (curr_installdir);
+    const char *rp = strnul (rel_installdir);
+    const char *cp = strnul (curr_installdir);
     const char *cp_base =
       curr_installdir + FILE_SYSTEM_PREFIX_LEN (curr_installdir);
 
diff --git a/lib/setlocale.c b/lib/setlocale.c
index c4f006105d17..3871a3fa1635 100644
--- a/lib/setlocale.c
+++ b/lib/setlocale.c
@@ -767,7 +767,7 @@ setlocale_unixlike (int category, const char *locale)
             const char *territory_start = underscore + 1;
             const char *territory_end = strchr (territory_start, '@');
             if (territory_end == NULL)
-              territory_end = territory_start + strlen (territory_start);
+              territory_end = strnul (territory_start);
 
             char ll_buf[64];
             memcpy (ll_buf, llCC_buf, underscore - llCC_buf);
diff --git a/lib/strftime.c b/lib/strftime.c
index 8d32023729ce..33fa2e017bb9 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -1358,7 +1358,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
             mbstate_t mbstate = mbstate_zero;
 
             if (! format_end)
-              format_end = f + strlen (f) + 1;
+              format_end = strnul (f) + 1;
             size_t fsize = format_end - f;
 
             size_t len = 0;
diff --git a/lib/striconv.c b/lib/striconv.c
index 6aded51e1499..bf169822d858 100644
--- a/lib/striconv.c
+++ b/lib/striconv.c
@@ -258,7 +258,7 @@ str_cd_iconv (const char *src, iconv_t cd)
 
     for (;;)
       {
-        /* Here inptr + inbytes_remaining = src + strlen (src),
+        /* Here inptr + inbytes_remaining = strnul (src),
                 outptr + outbytes_remaining = result + result_size - 1.  */
         size_t res = iconv (cd,
                             (ICONV_CONST char **) &inptr, &inbytes_remaining,
diff --git a/lib/string.in.h b/lib/string.in.h
index 599203c44db9..0207864b6fa6 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -813,6 +813,8 @@ streq (char const *__s1, char const *__s2)
 # endif
 #endif
 
+#define strnul(s)  strchr(s, '\0')
+
 /* Append no more than N characters from SRC onto DEST.  */
 #if @GNULIB_STRNCAT@
 # if @REPLACE_STRNCAT@
diff --git a/lib/strncat.c b/lib/strncat.c
index 5e77ea8846fd..5441ac756bc3 100644
--- a/lib/strncat.c
+++ b/lib/strncat.c
@@ -23,7 +23,7 @@
 char *
 strncat (char *dest, const char *src, size_t n)
 {
-  char *destptr = dest + strlen (dest);
+  char *destptr = strnul (dest);
 
   for (; n > 0 && (*destptr = *src) != '\0'; src++, destptr++, n--)
     ;
diff --git a/lib/term-style-control.c b/lib/term-style-control.c
index 9ab1c8ac087e..4ed5bf7e0af0 100644
--- a/lib/term-style-control.c
+++ b/lib/term-style-control.c
@@ -215,7 +215,7 @@ log_signal_handler_called (int sig)
 {
   char message[100];
   strcpy (message, "Signal handler for signal ");
-  simple_signal_string (message + strlen (message), sig);
+  simple_signal_string (strnul (message), sig);
   strcat (message, " called.\n");
   log_message (message);
 }
@@ -434,9 +434,9 @@ tcsetattr_failed (char message[100], const char *caller)
   int errnum = errno;
   strcpy (message, caller);
   strcat (message, ": tcsetattr(fd=");
-  sprintf_integer (message + strlen (message), active_fd);
+  sprintf_integer (strnul (message), active_fd);
   strcat (message, ") failed, errno=");
-  simple_errno_string (message + strlen (message), errnum);
+  simple_errno_string (strnul (message), errnum);
   strcat (message, "\n");
 }
 
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 12bdd45ba137..6763bd705364 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -3467,7 +3467,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   else
                     {
                       /* Use the entire string.  */
-                      arg_end = arg + strlen (arg);
+                      arg_end = strnul (arg);
                       /* The number of characters doesn't matter.  */
                       characters = 0;
                     }
diff --git a/lib/vc-mtime.c b/lib/vc-mtime.c
index ad47ef9e5ed4..208a3d2c36f1 100644
--- a/lib/vc-mtime.c
+++ b/lib/vc-mtime.c
@@ -250,7 +250,7 @@ git_mtime (struct timespec *mtime, const char *filename)
           char *endptr;
           unsigned long git_log_time;
           if (xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK
-              && endptr == line + strlen (line))
+              && endptr == strnul (line))
             {
               mtime->tv_sec = git_log_time;
               mtime->tv_nsec = 0;
@@ -885,7 +885,7 @@ max_vc_mtime (struct timespec *max_of_mtimes,
                             char *endptr;
                             unsigned long git_log_time;
                             if (!(xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK
-                                  && endptr == line + strlen (line)))
+                                  && endptr == strnul (line)))
                               {
                                 fprintf (stderr, "vc-mtime: git log output not as expected\n");
                                 goto git_log_fail1;
-- 
2.51.0

From 959a9d8e9a58ed6c151a6a84f2fa85aa55664608 Mon Sep 17 00:00:00 2001
Message-ID: <959a9d8e9a58ed6c151a6a84f2fa85aa55664608.1771768913.git....@kernel.org>
In-Reply-To: <3f2f41c6699c725c1b499feb94ee37c1e64db8d2.1771768913.git....@kernel.org>
References: <3f2f41c6699c725c1b499feb94ee37c1e64db8d2.1771768913.git....@kernel.org>
From: Alejandro Colomar <[email protected]>
Date: Sun, 22 Feb 2026 15:00:57 +0100
Subject: [PATCH 2/2] Use strnul(3) where it's suitable

Signed-off-by: Alejandro Colomar <[email protected]>
---
 lib/file-has-acl.c   | 2 +-
 lib/getopt.c         | 2 +-
 lib/inet_ntop.c      | 2 +-
 lib/time_rz.c        | 2 +-
 tests/test-savedir.c | 4 ++--
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index 26d3e358de7a..3269d7f71b7e 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -145,7 +145,7 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr)
   if (0 < ai->size)
     {
       char const *blim = ai->buf + ai->size;
-      for (char const *b = ai->buf; b < blim; b += strlen (b) + 1)
+      for (char const *b = ai->buf; b < blim; b = strnul (b) + 1)
         for (char const *a = xattr; *a == *b; a++, b++)
           if (!*a)
             return true;
diff --git a/lib/getopt.c b/lib/getopt.c
index 406a406b9bfa..9df03cf5e9bc 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -302,7 +302,7 @@ process_long_option (int argc, char **argv, const char *optstring,
 		}
 	    }
 	  free (ambig_malloced);
-	  d->__nextchar += strlen (d->__nextchar);
+	  d->__nextchar = strnul (d->__nextchar);
 	  d->optind++;
 	  d->optopt = 0;
 	  return '?';
diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c
index 599ca4fb723a..dff25c5f6d33 100644
--- a/lib/inet_ntop.c
+++ b/lib/inet_ntop.c
@@ -225,7 +225,7 @@ inet_ntop6 (const unsigned char *src, char *dst, socklen_t size)
         {
           if (!inet_ntop4 (src + 12, tp, sizeof tmp - (tp - tmp)))
             return (NULL);
-          tp += strlen (tp);
+          tp = strnul (tp);
           break;
         }
       {
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 811240e6da16..0e8ea47e7916 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -146,7 +146,7 @@ save_abbr (timezone_t tz, struct tm *tm)
               break;
             }
 
-          zone_copy += strlen (zone_copy) + 1;
+          zone_copy = strnul (zone_copy) + 1;
           if (!*zone_copy && tz->next)
             {
               tz = tz->next;
diff --git a/tests/test-savedir.c b/tests/test-savedir.c
index 95abc7833bb9..c95408c52fad 100644
--- a/tests/test-savedir.c
+++ b/tests/test-savedir.c
@@ -44,7 +44,7 @@ test_savedir_sort_none (void)
   memset (seen, 0, sizeof seen);
 
   /* Scan through the file names.  */
-  for (char *namep = name_space; *namep != '\0'; namep += strlen (namep) + 1)
+  for (char *namep = name_space; *namep != '\0'; namep = strnul (namep) + 1)
     {
       int index = *namep - 'a';
       ASSERT (strlen (namep) == 1);
@@ -68,7 +68,7 @@ test_savedir_sort_name (void)
 
   /* Check that files "a" to "z" appear in order.  */
   for (char *namep = name_space; *namep != '\0';
-       namep += strlen (namep) + 1, i += 1)
+       namep = strnul (namep) + 1, i += 1)
     {
       ASSERT (strlen (namep) == 1);
       ASSERT (*namep - 'a' == i);
-- 
2.51.0

Attachment: signature.asc
Description: PGP signature

Reply via email to