From: Collin Funk Date: Fri, 10 Oct 2025 03:36:15 +0000 (-0700) Subject: getdelim: Work around a glibc bug. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c06522b17cc60c6b57efc3aebb88fe605dc28ba1;p=thirdparty%2Fgnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index ec2d9651a5..bb326cdfdf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2025-10-10 Collin Funk + + 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 stdcountof-h tests: Test more kinds of string literals. diff --git a/doc/posix-functions/getdelim.texi b/doc/posix-functions/getdelim.texi index d166e61e3b..5801452212 100644 --- a/doc/posix-functions/getdelim.texi +++ b/doc/posix-functions/getdelim.texi @@ -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: diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 index 63d8830649..b996ffd104 100644 --- a/m4/getdelim.m4 +++ b/m4/getdelim.m4 @@ -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 # include @@ -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 -#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 ;;