X-Git-Url: https://git.deb.at/?a=blobdiff_plain;f=intl%2Fprintf.c;h=b7cdc5d82a0f7a865886db4305c6d9d9f70aed67;hb=84ddcd15cab7dc38bfad90348668c1bd5dc727f8;hp=878646c2de5e675b6cfb1aea36cba360dcf08bd7;hpb=4b8f9231090ada43f7e16987ec46ac7f45a914ec;p=pkg%2Fabook.git diff --git a/intl/printf.c b/intl/printf.c index 878646c..b7cdc5d 100644 --- a/intl/printf.c +++ b/intl/printf.c @@ -1,5 +1,5 @@ /* Formatted output to strings, using POSIX/XSI format strings with positions. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2006-2007, 2009 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software; you can redistribute it and/or modify it @@ -14,7 +14,7 @@ You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H @@ -47,13 +47,22 @@ char *alloca (); #if !HAVE_POSIX_PRINTF +#include +#include #include #include +/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ +#ifndef EOVERFLOW +# define EOVERFLOW E2BIG +#endif + /* When building a DLL, we must export some functions. Note that because the functions are only defined for binary backward compatibility, we don't need to use __declspec(dllimport) in any case. */ -#if defined _MSC_VER && BUILDING_DLL +#if HAVE_VISIBILITY && BUILDING_DLL +# define DLL_EXPORTED __attribute__((__visibility__("default"))) +#elif defined _MSC_VER && BUILDING_DLL # define DLL_EXPORTED __declspec(dllexport) #else # define DLL_EXPORTED @@ -61,6 +70,14 @@ char *alloca (); #define STATIC static +/* This needs to be consistent with libgnuintl.h.in. */ +#if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__ +/* Don't break __attribute__((format(printf,M,N))). + This redefinition is only possible because the libc in NetBSD, Cygwin, + mingw does not have a function __printf__. */ +# define libintl_printf __printf__ +#endif + /* Define auxiliary functions declared in "printf-args.h". */ #include "printf-args.c" @@ -87,11 +104,17 @@ libintl_vfprintf (FILE *stream, const char *format, va_list args) char *result = libintl_vasnprintf (NULL, &length, format, args); int retval = -1; if (result != NULL) - { - if (fwrite (result, 1, length, stream) == length) - retval = length; - free (result); - } + { + size_t written = fwrite (result, 1, length, stream); + free (result); + if (written == length) + { + if (length > INT_MAX) + errno = EOVERFLOW; + else + retval = length; + } + } return retval; } } @@ -140,12 +163,17 @@ libintl_vsprintf (char *resultbuf, const char *format, va_list args) size_t length = (size_t) ~0 / (4 * sizeof (char)); char *result = libintl_vasnprintf (resultbuf, &length, format, args); if (result != resultbuf) - { - free (result); - return -1; - } + { + free (result); + return -1; + } + if (length > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } else - return length; + return length; } } @@ -183,19 +211,23 @@ libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list a size_t maxlength = length; char *result = libintl_vasnprintf (resultbuf, &length, format, args); if (result != resultbuf) - { - if (maxlength > 0) - { - if (length < maxlength) - abort (); - memcpy (resultbuf, result, maxlength - 1); - resultbuf[maxlength - 1] = '\0'; - } - free (result); - return -1; - } + { + if (maxlength > 0) + { + size_t pruned_length = + (length < maxlength ? length : maxlength - 1); + memcpy (resultbuf, result, pruned_length); + resultbuf[pruned_length] = '\0'; + } + free (result); + } + if (length > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } else - return length; + return length; } } @@ -224,6 +256,12 @@ libintl_vasprintf (char **resultp, const char *format, va_list args) char *result = libintl_vasnprintf (NULL, &length, format, args); if (result == NULL) return -1; + if (length > INT_MAX) + { + free (result); + errno = EOVERFLOW; + return -1; + } *resultp = result; return length; } @@ -249,7 +287,12 @@ libintl_asprintf (char **resultp, const char *format, ...) #define WIDE_CHAR_VERSION 1 +#include "wprintf-parse.h" /* Define auxiliary functions declared in "wprintf-parse.h". */ +#define CHAR_T wchar_t +#define DIRECTIVE wchar_t_directive +#define DIRECTIVES wchar_t_directives +#define PRINTF_PARSE wprintf_parse #include "printf-parse.c" /* Define functions declared in "vasnprintf.h". */ @@ -280,15 +323,20 @@ libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args) wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args); int retval = -1; if (result != NULL) - { - size_t i; - for (i = 0; i < length; i++) - if (fputwc (result[i], stream) == WEOF) - break; - if (i == length) - retval = length; - free (result); - } + { + size_t i; + for (i = 0; i < length; i++) + if (fputwc (result[i], stream) == WEOF) + break; + free (result); + if (i == length) + { + if (length > INT_MAX) + errno = EOVERFLOW; + else + retval = length; + } + } return retval; } } @@ -337,19 +385,29 @@ libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_ size_t maxlength = length; wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args); if (result != resultbuf) - { - if (maxlength > 0) - { - if (length < maxlength) - abort (); - memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t)); - resultbuf[maxlength - 1] = 0; - } - free (result); - return -1; - } + { + if (maxlength > 0) + { + size_t pruned_length = + (length < maxlength ? length : maxlength - 1); + memcpy (resultbuf, result, pruned_length * sizeof (wchar_t)); + resultbuf[pruned_length] = 0; + } + free (result); + /* Unlike vsnprintf, which has to return the number of character that + would have been produced if the resultbuf had been sufficiently + large, the vswprintf function has to return a negative value if + the resultbuf was not sufficiently large. */ + if (length >= maxlength) + return -1; + } + if (length > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } else - return length; + return length; } }