X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=intl%2Fvasnprintf.c;h=8b073103bd344f8c13faaf47a8b556e069b18b1d;hb=ad91dd139c4d6665704b11d9bd34770c3b769543;hp=8a62282d73e4aec341776bac1605e6abf8ad1ff7;hpb=b02093873e853ba0caabae0451b51a2a119e7379;p=lyx.git diff --git a/intl/vasnprintf.c b/intl/vasnprintf.c index 8a62282d73..8b073103bd 100644 --- a/intl/vasnprintf.c +++ b/intl/vasnprintf.c @@ -1,5 +1,5 @@ /* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2002-2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published @@ -13,7 +13,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. */ /* Tell glibc's to provide a prototype for snprintf(). @@ -23,9 +23,7 @@ # define _GNU_SOURCE 1 #endif -#ifdef HAVE_CONFIG_H -# include -#endif +#include #ifndef IN_LIBINTL # include #endif @@ -251,7 +249,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar case TYPE_COUNT_LONGINT_POINTER: *a.arg[dp->arg_index].a.a_count_longint_pointer = length; break; -#ifdef HAVE_LONG_LONG +#ifdef HAVE_LONG_LONG_INT case TYPE_COUNT_LONGLONGINT_POINTER: *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; break; @@ -316,9 +314,8 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar const CHAR_T *digitp = dp->precision_start + 1; precision = 0; - do + while (digitp != dp->precision_end) precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - while (digitp != dp->precision_end); } } @@ -326,44 +323,43 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar { case 'd': case 'i': case 'u': -# ifdef HAVE_LONG_LONG +# ifdef HAVE_LONG_LONG_INT if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ ) - + 1 /* turn floor into ceil */ - + 1; /* account for leading sign */ + + 1; /* turn floor into ceil */ else # endif if (type == TYPE_LONGINT || type == TYPE_ULONGINT) tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ ) - + 1 /* turn floor into ceil */ - + 1; /* account for leading sign */ + + 1; /* turn floor into ceil */ else tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ ) - + 1 /* turn floor into ceil */ - + 1; /* account for leading sign */ + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Multiply by 2, as an estimate for FLAG_GROUP. */ + tmp_length = xsum (tmp_length, tmp_length); + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); break; case 'o': -# ifdef HAVE_LONG_LONG +# ifdef HAVE_LONG_LONG_INT if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.333334 /* binary -> octal */ ) - + 1 /* turn floor into ceil */ - + 1; /* account for leading sign */ + + 1; /* turn floor into ceil */ else # endif if (type == TYPE_LONGINT || type == TYPE_ULONGINT) @@ -371,26 +367,27 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.333334 /* binary -> octal */ ) - + 1 /* turn floor into ceil */ - + 1; /* account for leading sign */ + + 1; /* turn floor into ceil */ else tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.333334 /* binary -> octal */ ) - + 1 /* turn floor into ceil */ - + 1; /* account for leading sign */ + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); break; case 'x': case 'X': -# ifdef HAVE_LONG_LONG +# ifdef HAVE_LONG_LONG_INT if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */ ) - + 1 /* turn floor into ceil */ - + 2; /* account for leading sign or alternate form */ + + 1; /* turn floor into ceil */ else # endif if (type == TYPE_LONGINT || type == TYPE_ULONGINT) @@ -398,15 +395,17 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */ ) - + 1 /* turn floor into ceil */ - + 2; /* account for leading sign or alternate form */ + + 1; /* turn floor into ceil */ else tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.25 /* binary -> hexadecimal */ ) - + 1 /* turn floor into ceil */ - + 2; /* account for leading sign or alternate form */ + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 2, to account for a leading sign or alternate form. */ + tmp_length = xsum (tmp_length, 2); break; case 'f': case 'F': @@ -529,7 +528,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar switch (type) { -#ifdef HAVE_LONG_LONG +#ifdef HAVE_LONG_LONG_INT case TYPE_LONGLONGINT: case TYPE_ULONGLONGINT: *p++ = 'l'; @@ -683,7 +682,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar SNPRINTF_BUF (arg); } break; -#ifdef HAVE_LONG_LONG +#ifdef HAVE_LONG_LONG_INT case TYPE_LONGLONGINT: { long long int arg = a.arg[dp->arg_index].a.a_longlongint; @@ -864,6 +863,10 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar free (buf_malloced); CLEANUP (); *lengthp = length; + /* Note that we can produce a big string of a length > INT_MAX. POSIX + says that snprintf() fails with errno = EOVERFLOW in this case, but + that's only because snprintf() returns an 'int'. This function does + not have this limitation. */ return result; out_of_memory: