]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
getdelim: Work around a glibc bug.
authorCollin Funk <collin.funk1@gmail.com>
Fri, 10 Oct 2025 03:36:15 +0000 (20:36 -0700)
committerCollin Funk <collin.funk1@gmail.com>
Sat, 11 Oct 2025 00:34:51 +0000 (17:34 -0700)
* m4/getdelim.m4 (gl_FUNC_GETDELIM): Check that the buffer is terminated
with a NUL character when the first character read is EOF. Guess that
the function does not work on glibc.
* doc/posix-functions/getdelim.texi: Mention the bug.

ChangeLog
doc/posix-functions/getdelim.texi
m4/getdelim.m4

index ec2d9651a5b2dfd98ab6d3b06c0d298688ce5933..bb326cdfdf77510a0863c283e6718edf0c783c40 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-10-10  Collin Funk  <collin.funk1@gmail.com>
+
+       getdelim: Work around a glibc bug.
+       * m4/getdelim.m4 (gl_FUNC_GETDELIM): Check that the buffer is terminated
+       with a NUL character when the first character read is EOF. Guess that
+       the function does not work on glibc.
+       * doc/posix-functions/getdelim.texi: Mention the bug.
+
 2025-10-08  Bruno Haible  <bruno@clisp.org>
 
        stdcountof-h tests: Test more kinds of string literals.
index d166e61e3b1264093f6fcb87d4585f73e00f57f3..5801452212356fcb9c247250e90ebed8630aaca0 100644 (file)
@@ -19,6 +19,11 @@ macOS 10.13.
 This function crashes when passed a pointer to a NULL buffer together with a
 pointer to a non-zero buffer size on some platforms:
 FreeBSD 8.0.
+@item
+This function does not NUL terminate the buffer when the first
+character read is EOF on some platforms:
+@c https://sourceware.org/PR28038
+glibc 2.42.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 63d8830649a3556451fbdbf98e1e40e43e2771a8..b996ffd104499f5eb1fe45d94a219dfe84e64724 100644 (file)
@@ -1,5 +1,5 @@
 # getdelim.m4
-# serial 19
+# serial 20
 
 dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc.
 dnl
@@ -37,6 +37,7 @@ AC_DEFUN([gl_FUNC_GETDELIM],
            gl_cv_func_working_getdelim=no ;;
          *)
            echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
+           touch conftest.empty
            AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #    include <stdio.h>
 #    include <stdlib.h>
@@ -44,6 +45,7 @@ AC_DEFUN([gl_FUNC_GETDELIM],
     int main ()
     {
       FILE *in = fopen ("./conftest.data", "r");
+      int result = 0;
       if (!in)
         return 1;
       {
@@ -53,7 +55,7 @@ AC_DEFUN([gl_FUNC_GETDELIM],
         size_t siz = 0;
         int len = getdelim (&line, &siz, '\n', in);
         if (!(len == 4 && line && strcmp (line, "foo\n") == 0))
-          { free (line); fclose (in); return 2; }
+          result |= 2;
         free (line);
       }
       {
@@ -62,36 +64,41 @@ AC_DEFUN([gl_FUNC_GETDELIM],
         char *line = NULL;
         size_t siz = (size_t)(~0) / 4;
         if (getdelim (&line, &siz, '\n', in) == -1)
-          { fclose (in); return 3; }
+          result |= 4;
         free (line);
       }
       fclose (in);
-      return 0;
+      {
+        /* Test that reading EOF as the first character sets the first byte
+           in the buffer to NUL.  This fails on glibc 2.42 and earlier.  */
+        in = fopen ("./conftest.empty", "r");
+        if (!in)
+          return 1;
+        char *line = malloc (1);
+        line[0] = 'A';
+        size_t siz = 1;
+        if (getdelim (&line, &siz, '\n', in) != -1 || line[0] != '\0')
+          result |= 8;
+        free (line);
+      }
+      fclose (in);
+      return result;
     }
     ]])],
              [gl_cv_func_working_getdelim=yes],
              [gl_cv_func_working_getdelim=no],
-             [dnl We're cross compiling.
-              dnl Guess it works on glibc2 systems and musl systems.
-              AC_EGREP_CPP([Lucky GNU user],
-                [
-#include <features.h>
-#ifdef __GNU_LIBRARY__
- #if (__GLIBC__ >= 2) && !defined __UCLIBC__
-  Lucky GNU user
- #endif
-#endif
-                ],
-                [gl_cv_func_working_getdelim="guessing yes"],
-                [case "$host_os" in
-                   *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;;
-                   *)                  gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
-                 esac
-                ])
+             [case "$host_os" in
+                                    # Guess yes on musl.
+                *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;;
+                                    # Guess no on glibc.
+                *-gnu* | gnu*)      gl_cv_func_working_getdelim="guessing no" ;;
+                *)                  gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
+              esac
              ])
            ;;
        esac
-      ])
+       rm -f conftest.data conftest.empty
+    ])
     case "$gl_cv_func_working_getdelim" in
       *yes) ;;
       *) REPLACE_GETDELIM=1 ;;