X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fvasnprintf.c;h=ff80857305864a2ac93d98d7159af9048a67c7cf;hb=8912e6d4dccc2f3b7d125229ef9ee05dda1f36ed;hp=e40994d0c8164229952cda37248b721507098cdc;hpb=bd49eb7d1f07c6e63ee83c0af94713b1fb3e12c2;p=gnulib.git diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index e40994d0c..ff8085730 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -1,5 +1,5 @@ /* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2002-2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ #include /* abort(), malloc(), realloc(), free() */ #include /* memcpy(), strlen() */ #include /* errno */ -#include /* CHAR_BIT */ +#include /* CHAR_BIT, INT_MAX */ #include /* DBL_MAX_EXP, LDBL_MAX_EXP */ #if WIDE_CHAR_VERSION # include "wprintf-parse.h" @@ -222,7 +222,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar { size_t augmented_length; - if (!(dp->arg_index < 0)) + if (!(dp->arg_index == ARG_NONE)) abort (); augmented_length = xsum (length, 1); ENSURE_ALLOCATION (augmented_length); @@ -231,7 +231,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar } else { - if (!(dp->arg_index >= 0)) + if (!(dp->arg_index != ARG_NONE)) abort (); if (dp->conversion == 'n') @@ -279,7 +279,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar width = 0; if (dp->width_start != dp->width_end) { - if (dp->width_arg_index >= 0) + if (dp->width_arg_index != ARG_NONE) { int arg; @@ -301,7 +301,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar precision = 6; if (dp->precision_start != dp->precision_end) { - if (dp->precision_arg_index >= 0) + if (dp->precision_arg_index != ARG_NONE) { int arg; @@ -315,9 +315,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); } } @@ -563,13 +562,13 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar /* Construct the arguments for calling snprintf or sprintf. */ prefix_count = 0; - if (dp->width_arg_index >= 0) + if (dp->width_arg_index != ARG_NONE) { if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; } - if (dp->precision_arg_index >= 0) + if (dp->precision_arg_index != ARG_NONE) { if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) abort (); @@ -863,8 +862,19 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar free (buf_malloced); CLEANUP (); *lengthp = length; + if (length > INT_MAX) + goto length_overflow; return result; + length_overflow: + /* We could produce such a big string, but its length doesn't fit into + an 'int'. POSIX says that snprintf() fails with errno = EOVERFLOW in + this case. */ + if (result != resultbuf) + free (result); + errno = EOVERFLOW; + return NULL; + out_of_memory: if (!(result == resultbuf || result == NULL)) free (result);