X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=intl%2Fprintf.c;h=004c66f783d1914199507d4c0ce78a879364d84d;hb=3408ca42044616bd169540ec901ce248e8290a61;hp=5e112b69bf42130567eb203bdd824dc37a5a0589;hpb=f84a1c6e5c6173e7d0aea0fb2adde988ee5f7b27;p=lyx.git diff --git a/intl/printf.c b/intl/printf.c index 5e112b69bf..004c66f783 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 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software; you can redistribute it and/or modify it @@ -47,9 +47,16 @@ 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. */ @@ -61,6 +68,14 @@ char *alloca (); #define STATIC static +/* This needs to be consistent with libgnuintl.h.in. */ +#if defined __NetBSD__ || 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" @@ -88,9 +103,15 @@ libintl_vfprintf (FILE *stream, const char *format, va_list args) int retval = -1; if (result != NULL) { - if (fwrite (result, 1, length, stream) == length) - retval = length; + size_t written = fwrite (result, 1, length, stream); free (result); + if (written == length) + { + if (length > INT_MAX) + errno = EOVERFLOW; + else + retval = length; + } } return retval; } @@ -144,6 +165,11 @@ libintl_vsprintf (char *resultbuf, const char *format, va_list args) free (result); return -1; } + if (length > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } else return length; } @@ -186,12 +212,16 @@ libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list a { if (maxlength > 0) { - if (length < maxlength) - abort (); - memcpy (resultbuf, result, maxlength - 1); - resultbuf[maxlength - 1] = '\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 @@ -224,6 +254,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; } @@ -285,9 +321,14 @@ libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args) for (i = 0; i < length; i++) if (fputwc (result[i], stream) == WEOF) break; - if (i == length) - retval = length; free (result); + if (i == length) + { + if (length > INT_MAX) + errno = EOVERFLOW; + else + retval = length; + } } return retval; } @@ -340,12 +381,22 @@ libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_ { if (maxlength > 0) { - if (length < maxlength) - abort (); - memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t)); - resultbuf[maxlength - 1] = 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