* lib/xvasprintf.h: Clarify the programmer's responsibilities.
(xasprintf, xvasprintf): Declare as returning non-NULL.
* lib/xvasprintf.c: Include <stdlib.h>.
(xstrcat): Allow results longer than INT_MAX characters. Upon size
overflow, invoke xalloc_die.
(xvasprintf): Call vazsprintf instead of vasprintf. When some other
error occurs, emit an error message and abort.
* m4/strerrorname_np.m4 (gl_CHECK_STRERRORNAME_NP): New macro, extracted
from gl_FUNC_STRERRORNAME_NP.
(gl_FUNC_STRERRORNAME_NP): Invoke it.
(gl_OPTIONAL_STRERRORNAME_NP): New macro.
* m4/xvasprintf.m4 (gl_XVASPRINTF): Invoke gl_OPTIONAL_STRERRORNAME_NP.
* modules/xvasprintf (Files): Add m4/strerrorname_np.m4.
(Depends-on): Add extensions, vazsprintf. Remove vasprintf.
* NEWS: Mention the change.
+2024-06-22 Bruno Haible <bruno@clisp.org>
+
+ xvasprintf: Guarantee a non-NULL result.
+ * lib/xvasprintf.h: Clarify the programmer's responsibilities.
+ (xasprintf, xvasprintf): Declare as returning non-NULL.
+ * lib/xvasprintf.c: Include <stdlib.h>.
+ (xstrcat): Allow results longer than INT_MAX characters. Upon size
+ overflow, invoke xalloc_die.
+ (xvasprintf): Call vazsprintf instead of vasprintf. When some other
+ error occurs, emit an error message and abort.
+ * m4/strerrorname_np.m4 (gl_CHECK_STRERRORNAME_NP): New macro, extracted
+ from gl_FUNC_STRERRORNAME_NP.
+ (gl_FUNC_STRERRORNAME_NP): Invoke it.
+ (gl_OPTIONAL_STRERRORNAME_NP): New macro.
+ * m4/xvasprintf.m4 (gl_XVASPRINTF): Invoke gl_OPTIONAL_STRERRORNAME_NP.
+ * modules/xvasprintf (Files): Add m4/strerrorname_np.m4.
+ (Depends-on): Add extensions, vazsprintf. Remove vasprintf.
+ * NEWS: Mention the change.
+
2024-06-22 Bruno Haible <bruno@clisp.org>
vasprintf: Make return convention consistent with other modules.
Date Modules Changes
+2024-06-22 xvasprintf It is now the programmer's responsibility to pass
+ a valid format string without %ls, %lc directives
+ and that all widths are >= -INT_MAX and <= INT_MAX.
+
2024-05-16 putenv This module is renamed to 'putenv-gnu'.
2024-02-21 *printf-posix These modules no longer support the 'n' directive
#include <errno.h>
#include <limits.h>
-#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include "xalloc.h"
}
va_end (ap);
- /* Test for overflow in the summing pass above or in (totalsize + 1) below.
- Also, don't return a string longer than INT_MAX, for consistency with
- vasprintf(). */
- if (totalsize == SIZE_MAX || totalsize > INT_MAX)
- {
- errno = EOVERFLOW;
- return NULL;
- }
+ /* Test for overflow in the summing pass above or in (totalsize + 1)
+ below. */
+ if (totalsize == SIZE_MAX)
+ xalloc_die ();
/* Allocate and fill the result string. */
result = XNMALLOC (totalsize + 1, char);
}
}
- if (vasprintf (&result, format, args) < 0)
+ if (vazsprintf (&result, format, args) < 0)
{
if (errno == ENOMEM)
xalloc_die ();
- return NULL;
+ else
+ {
+ /* The programmer ought to have ensured that none of the other errors
+ can occur. */
+ int err = errno;
+ char errbuf[20];
+ const char *errname;
+#if HAVE_WORKING_STRERRORNAME_NP
+ errname = strerrorname_np (err);
+ if (errname == NULL)
+#else
+ if (err == EINVAL)
+ errname = "EINVAL";
+ else if (err == EILSEQ)
+ errname = "EILSEQ";
+ else if (err == EOVERFLOW)
+ errname = "EOVERFLOW";
+ else
+#endif
+ {
+ sprintf (errbuf, "%d", err);
+ errname = errbuf;
+ }
+ fprintf (stderr, "vasprintf failed! format=\"%s\", errno=%s\n",
+ format, errname);
+ fflush (stderr);
+ abort ();
+ }
}
return result;
#ifndef _XVASPRINTF_H
#define _XVASPRINTF_H
-/* This file uses _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_MALLOC. */
+/* This file uses _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_MALLOC,
+ _GL_ATTRIBUTE_RETURNS_NONNULL. */
#if !_GL_CONFIG_H_INCLUDED
#error "Please include config.h first."
#endif
extern "C" {
#endif
-/* Write formatted output to a string dynamically allocated with malloc(),
- and return it. Upon [ENOMEM] memory allocation error, call xalloc_die.
- On some other error
- - [EOVERFLOW] resulting string length is > INT_MAX,
+/* Prints formatted output to a string dynamically allocated with malloc(),
+ and returns it. Upon [ENOMEM] memory allocation error, it calls xalloc_die.
+
+ It is the responsibility of the programmer to ensure that
+ - the format string is valid,
+ - the format string does not use %ls or %lc directives, and
+ - all widths in the format string and passed as arguments are >= -INT_MAX
+ and <= INT_MAX,
+ so that other errors
- [EINVAL] invalid format string,
- [EILSEQ] error during conversion between wide and multibyte characters,
- return NULL. */
+ - [EOVERFLOW] some specified width is > INT_MAX,
+ cannot occur. */
extern char *xasprintf (const char *format, ...)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
- _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 1, 2));
+ _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 1, 2))
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
extern char *xvasprintf (const char *format, va_list args)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
- _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 1, 0));
+ _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 1, 0))
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
#ifdef __cplusplus
}
# strerrorname_np.m4
-# serial 5
+# serial 6
dnl Copyright (C) 2020-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
[
AC_REQUIRE([gl_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_CHECK_STRERRORNAME_NP])
+ if test $ac_cv_func_strerrorname_np = yes; then
+ case "$gl_cv_func_strerrorname_np_works" in
+ *yes) ;;
+ *) REPLACE_STRERRORNAME_NP=1 ;;
+ esac
+ else
+ HAVE_STRERRORNAME_NP=0
+ fi
+])
+
+# Check for a working strerrorname_np function.
+# Sets ac_cv_func_strerrorname_np, gl_cv_func_strerrorname_np_works.
+AC_DEFUN([gl_CHECK_STRERRORNAME_NP],
+[
dnl Persuade glibc <string.h> to declare strerrorname_np().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
esac
])
])
+ fi
+])
+
+# Prerequisite for using strerrorname_np when available.
+AC_DEFUN_ONCE([gl_OPTIONAL_STRERRORNAME_NP],
+[
+ AC_REQUIRE([gl_CHECK_STRERRORNAME_NP])
+ if test $ac_cv_func_strerrorname_np = yes; then
case "$gl_cv_func_strerrorname_np_works" in
- *yes) ;;
- *) REPLACE_STRERRORNAME_NP=1 ;;
+ *yes)
+ AC_DEFINE([HAVE_WORKING_STRERRORNAME_NP], [1],
+ [Define to 1 if the function strerrorname_np exists and works.])
+ ;;
esac
- else
- HAVE_STRERRORNAME_NP=0
fi
])
# xvasprintf.m4
-# serial 2
+# serial 3
dnl Copyright (C) 2006, 2009-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Prerequisites of lib/xvasprintf.c.
-AC_DEFUN([gl_XVASPRINTF], [:])
+AC_DEFUN([gl_XVASPRINTF], [
+ gl_OPTIONAL_STRERRORNAME_NP
+])
lib/xasprintf.c
lib/xalloc.h
m4/xvasprintf.m4
+m4/strerrorname_np.m4
Depends-on:
+extensions
stdio
-vasprintf
+vazsprintf
xalloc
xalloc-die
extern-inline