From: Bruno Haible Date: Sat, 22 Jun 2024 10:16:30 +0000 (+0200) Subject: sprintf-posix: Use vzsprintf. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=8a31e0648af657347c4ef3b8d823c464eced4b5a;p=gnulib.git sprintf-posix: Use vzsprintf. * lib/stdio.in.h (sprintf): Move specification to here. * lib/sprintf.c: Don't include , vasnprintf.h. Include . (sprintf): Implement based on vzsprintf. * modules/sprintf-posix (Depends-on): Add vzsprintf. Remove vasnprintf. --- diff --git a/ChangeLog b/ChangeLog index 96dc1dff2c..76c8dc4dce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2024-06-22 Bruno Haible + sprintf-posix: Use vzsprintf. + * lib/stdio.in.h (sprintf): Move specification to here. + * lib/sprintf.c: Don't include , vasnprintf.h. Include + . + (sprintf): Implement based on vzsprintf. + * modules/sprintf-posix (Depends-on): Add vzsprintf. Remove vasnprintf. + zsprintf: New module. * lib/stdio.in.h (zsprintf): New declaration, based on lib/sprintf.c. diff --git a/lib/sprintf.c b/lib/sprintf.c index ba0108d08c..d781b8c7b5 100644 --- a/lib/sprintf.c +++ b/lib/sprintf.c @@ -25,56 +25,24 @@ #include #include #include -#include -#include "vasnprintf.h" - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* Print formatted output to string STR. - Return string length of formatted string. On error, return a negative - value. */ int sprintf (char *str, const char *format, ...) { - char *output; - size_t len; - size_t lenbuf; va_list args; - - /* vasnprintf fails with EOVERFLOW when the buffer size argument is larger - than INT_MAX (if that fits into a 'size_t' at all). - Also note that glibc's iconv fails with E2BIG when we pass a length that - is so large that str + lenbuf wraps around, i.e. - (uintptr_t) (str + lenbuf) < (uintptr_t) str. - Therefore set lenbuf = min (SIZE_MAX, INT_MAX, - (uintptr_t) str - 1). */ - lenbuf = (SIZE_MAX < INT_MAX ? SIZE_MAX : INT_MAX); - if (lenbuf > ~ (uintptr_t) str) - lenbuf = ~ (uintptr_t) str; + ptrdiff_t ret; va_start (args, format); - output = vasnprintf (str, &lenbuf, format, args); - len = lenbuf; + ret = vzsprintf (str, format, args); va_end (args); - if (!output) - return -1; - - if (output != str) - { - /* len is near SIZE_MAX. */ - free (output); - errno = EOVERFLOW; - return -1; - } - - if (len > INT_MAX) +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) { errno = EOVERFLOW; return -1; } +#endif - return len; + return ret; } diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 17c662f45a..5a70aa20ba 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -1521,6 +1521,9 @@ _GL_CXXALIAS_SYS (zsprintf, ptrdiff_t, GNULIB_POSIXCHECK is defined. */ #if @GNULIB_SPRINTF_POSIX@ +/* Prints formatted output to string STR. + Returns the string length of the formatted string. Upon failure, + returns a negative value. */ # if @REPLACE_SPRINTF@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define sprintf rpl_sprintf diff --git a/modules/sprintf-posix b/modules/sprintf-posix index 589ad104ce..a1eb6127ad 100644 --- a/modules/sprintf-posix +++ b/modules/sprintf-posix @@ -18,7 +18,7 @@ stdio nocrash printf-safe multiarch -vasnprintf [test $REPLACE_SPRINTF = 1] +vzsprintf [test $REPLACE_SPRINTF = 1] isnand-nolibm [test $REPLACE_SPRINTF = 1] isnanl-nolibm [test $REPLACE_SPRINTF = 1] frexp-nolibm [test $REPLACE_SPRINTF = 1]